在后台运行应用时获取GPS位置更新

时间:2018-11-28 00:12:26

标签: android background gps location foreground-service

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

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

1 个答案:

答案 0 :(得分:0)

尝试下面的代码行

在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();
    }
}

}

希望对您有帮助