Getting GPS location updates while app in the background

点点圈 提交于 2020-12-15 06:22:39

问题


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.


回答1:


Try the below line of code

Write the below line of code in the 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>

Write the line of code from where you want to start service

LocationTracker.startLocationService(getApplicationContext());

Write the below code in service class

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

}

Hope it will help for you



来源:https://stackoverflow.com/questions/53510193/getting-gps-location-updates-while-app-in-the-background

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!