问题
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