在后台运行应用程序时获取GPS位置更新 [英] Getting GPS location updates while app in the background

查看:343
本文介绍了在后台运行应用程序时获取GPS位置更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个android应用程序,该应用程序跟踪客户位置并每10秒发送一次位置信息,但是,在android O中,每小时都会获取几次位置更新,如有关android O中gps位置更新限制的文档中所述无论如何,为了克服这个问题,我使用了带有通知的前台服务,以便gps位置更新在融合位置中保持更新. 之后,我面临另一个问题,即融合位置中的速度和方向为零,因为它从网络提供商和gps提供者那里获取位置,而当位置来自网络提供商时,速度和方向为零,而这些信息对我很重要,并且我将位置服务切换为LocationManager而不是fusedLocation,因此我只能确定gps提供程序,因为fusedLocation中不提供此功能. 但是我注意到,即使我使用前景服务,Android O中的LocationManager在后台时也不会获得位置更新.如何获得一种在后台不断更新位置并仅使用gps提供程序的解决方案?

I have an android application that tracks customer location and send it's location each 10 seconds, however, in android O, location updates will be gotten few times each hour, as said in the documentation about limitation of gps location update in android O. anyway, to overcome this problem, I used a foreground service with notification, so that the gps location update keep updating in fusedLocation. After that, I faced another problem that speed and direction in fusedLocation are zero, because it takes the location from both network provider and gps provider, when location is from network provider, the speed and direction are zeros, and these info are important for me, and I switched my location service to LocationManager instead of fusedLocation, so I can determine only the gps provider because this feature is not available in fusedLocation. But what I notice, that LocationManager in android O does not get location updates while in the background even though I use foreground service for that purpose. how can get a solution that keep updating location in background, and use only gps provider?

我没有代码片段,我只想讨论这个问题.

I don't have a code snipt, I just want to discuss this matter.

推荐答案

尝试下面的代码行

在AndroidManifest.xml中编写以下代码行

 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<application>
 <service
        android:name=".LocationTracker"
        android:stopWithTask="true"
        />
</application>

从您要开始服务的地方编写代码行

LocationTracker.startLocationService(getApplicationContext());

在服务类中写入以下代码

public class LocationTracker extends Service{

private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 1000;
private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = 1000;
private static int DISPLACEMENT = 0;

private FusedLocationProviderClient mFusedLocationClient;
private LocationRequest mLocationRequest;
private SettingsClient mSettingsClient;
private LocationSettingsRequest mLocationSettingsRequest;
private LocationCallback mLocationCallback;
private String TAG = LocationTracker.class.getSimpleName();
private final int NOTIFICATION_ID = 9083150;
public static final String CHANNEL_ID = "CHANNEL_ID";
public static final String CHANNEL_ID_NAME = "CHANNEL_ID_NAME";

@Override
public void onCreate() {
    super.onCreate();
    try {
        if (Build.VERSION.SDK_INT >= 26) {
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_ID_NAME,
                    NotificationManager.IMPORTANCE_HIGH);
            channel.setSound(null, null);
            channel.setShowBadge(false);
            NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.deleteNotificationChannel(CHANNEL_ID);
            notificationManager.createNotificationChannel(channel);

            Notification notification = createNotification(getApplicationContext(),CHANNEL_ID,0);
            if (notification == null) {
                notification = new NotificationCompat.Builder(this, CHANNEL_ID).build();
            }
            startForeground(NOTIFICATION_ID, notification);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private Notification createNotification(Context context, String channelid,int type) {
    try {
        return new NotificationCompat.Builder(context,channelid)
                .setContentTitle("")
                .setContentText("")
                .setOnlyAlertOnce(true)
                .setOngoing(true)
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setCategory(NotificationCompat.CATEGORY_SERVICE)
                .setVisibility(Notification.VISIBILITY_PRIVATE)
                .setSmallIcon(R.mipmap.ic_launcher)
                .build();

    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}


public void setLocationUpdateCallback() {
    try {
        mLocationCallback = null;
        mLocationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                super.onLocationResult(locationResult);
                Logger.i(TAG, "locationResult ==== " + locationResult);
            }
        };
    }catch (Exception e){
        e.printStackTrace();
    }
}

private void init() {
    try {
        setLocationUpdateCallback();
        mFusedLocationClient = null;
        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
        mSettingsClient = LocationServices.getSettingsClient(this);
        mLocationRequest = null;
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setSmallestDisplacement(DISPLACEMENT);

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(mLocationRequest);
        mLocationSettingsRequest = null;
        mLocationSettingsRequest = builder.build();

    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    init();
    startLocationUpdates();
    return START_STICKY;
}

@androidx.annotation.Nullable
@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

protected void startLocationUpdates() {
    mSettingsClient
            .checkLocationSettings(
                    mLocationSettingsRequest)
            .addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
                @SuppressLint("MissingPermission")
                @Override
                public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                    Log.e(TAG, "LocationSettingsStatusCodes onSuccess");
                    mFusedLocationClient.requestLocationUpdates(mLocationRequest,
                            mLocationCallback, Looper.myLooper());
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    int statusCode = ((ApiException) e).getStatusCode();
                    switch (statusCode) {
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            Log.e(TAG, "LocationSettingsStatusCodes.RESOLUTION_REQUIRED");
                            mFusedLocationClient.requestLocationUpdates(mLocationRequest,
                                    mLocationCallback, Looper.myLooper());
                            break;
                        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                            Log.e(TAG, "LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE");
                    }
                }
            });
}

public static void startLocationService(Context context) {
    try {
        Intent intent = new Intent(context, LocationTracker.class);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            ContextCompat.startForegroundService(context, intent);
        } else {
            context.startService(intent);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

希望对您有帮助

这篇关于在后台运行应用程序时获取GPS位置更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆