我已经制作了位置更新前台服务,当间隔小于30秒时直接获取位置(requestLocationUpdates),如果超过30秒,我使用ScheduledExecutorService获取位置结果和池位置结果以获得最佳位置。我遇到的唯一问题是当屏幕关闭时我没有获得位置更新。此代码运行良好,直到移动屏幕熄灭。
请注意它的前台服务。
我的代码如下:
private boolean currentlyProcessingLocation = false;
public static int intervalForLocationRequestMethod = 500;
public static int intervalForLocationUpdates = 30000;
public int locationUpdateMethodThreshold = 5000;
public int sameLocationCounter = 0;
boolean locationUpdateMethodChanged = false;
ScheduledExecutorService sch;
Runnable periodicTask = new Runnable() {
@Override
public void run() {
Log.i(TAG, "run: repeat ");
Intent i = new Intent(LocationService.this, LocationService.class);
i.setAction(Constants.ACTION.STARTLOCATIONREPEAT_ACTION);
startService(i);
}
};
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate: ");
buildGoogleApiClient();
if (intervalForLocationUpdates <= locationUpdateMethodThreshold) {
intervalForLocationRequestMethod = intervalForLocationUpdates;
}
showOnGoingLocationServiceNotification();
}
private void showOnGoingLocationServiceNotification() {
Log.i(TAG, "showOnGoingLocationServiceNotification: ");
Intent notificationIntent = new Intent(this, MapsActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MapsActivity.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("Forcee")
.setTicker("Forcee Tracking")
.setColor(Color.GREEN)
.setContentText("Forcee is tracking your location....Tap to stop")
.setSmallIcon(R.drawable.cast_ic_notification_small_icon)
.setWhen(System.currentTimeMillis())
.setContentIntent(resultPendingIntent)
.setOngoing(true).build();
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, notification);}
@Override
public void onConnected(@Nullable Bundle bundle) {
mLocationRequest = LocationRequest.create();
mLocationRequest.setFastestInterval(intervalForLocationRequestMethod);
mLocationRequest.setInterval(intervalForLocationRequestMethod);
if (intervalForLocationUpdates <= locationUpdateMethodThreshold || locationUpdateMethodChanged) {
mLocationRequest.setSmallestDisplacement(50);
}
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand: ");
Thread thread = new Thread(new LocationUpdateThread(intent, startId));
thread.start();
return START_STICKY;
}
@Override
public void onLocationChanged(Location location) {
Log.i(TAG, "onLocationChanged: " + location);
if (lastLocation != null) {
if (location.distanceTo(lastLocation) >= 40.0f && locationUpdateMethodChanged && location.getAccuracy() <= 100.0f) {
locationUpdateMethodChanged = false;
currentlyProcessingLocation = false;
sch = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1);
sch.scheduleAtFixedRate(periodicTask, intervalForLocationUpdates, intervalForLocationUpdates, TimeUnit.MILLISECONDS);
}
}
if (location.getAccuracy() <= 100.0f) {
if (firstLocationUpdateCall) {
updatingLocation(location);
firstLocationUpdateCall = false;
} else {
if (location.distanceTo(lastLocation) >= 40.0f) {
updatingLocation(location);
sameLocationCounter = 0;
} else {
if (intervalForLocationUpdates > locationUpdateMethodThreshold && !locationUpdateMethodChanged) {
sameLocationCounter++;
lastLocation = location;
Log.i(TAG, "onLocationChanged: " + sameLocationCounter);
if (sameLocationCounter == 5) {
locationUpdateMethodChanged = true;
intervalForLocationRequestMethod = 1000;
stopLocationUpdates();
sameLocationCounter = 0;
sch.shutdownNow();
sch = null;
Intent i = new Intent(LocationService.this, LocationService.class);
i.setAction(Constants.ACTION.STARTLOCATIONREPEAT_ACTION);
startService(i);
}
Log.i(TAG, "onLocationChanged: " + locationUpdateMethodChanged);
}
}
if (intervalForLocationUpdates> locationUpdateMethodThreshold && !locationUpdateMethodChanged) {
stopLocationUpdates();
Log.i(TAG, "onLocationChanged: stopcheckshift");
}
}
}
}
public void updatingLocation(Location location) {
lastLocation = location;
Log.i(TAG, "onLocationChanged: First " + locationPoints.size());
locationPoints.add(location);
Log.i(TAG, "onLocationChanged: Last " + locationPoints.size());
sendLocationsToActivity(locationPoints);
if (intervalForLocationUpdates > locationUpdateMethodThreshold) {
stopLocationUpdates();
}
}
public void sendLocationsToActivity(ArrayList<Location> locationPoints) {
Log.i(TAG, "sendLocationsToActivity: ");
Intent intent = new Intent("LocationUpdates");
intent.putParcelableArrayListExtra("Locations", locationPoints);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
private void stopLocationUpdates() {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, LocationService.this);
mGoogleApiClient.disconnect();
currentlyProcessingLocation = false;
}
}
final class LocationUpdateThread implements Runnable {
int service_id;
Intent intent;
LocationUpdateThread(Intent intent, int service_id) {
this.intent = intent;
this.service_id = service_id;
}
@Override
public void run() {
Log.i(TAG, "run: ");
if (intent != null) {
Log.i(TAG, "run: " + intent.getAction());
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
toastHandler("Tracking Started!");
mGoogleApiClient.connect();
currentlyProcessingLocation = true;
if (intervalForLocationUpdates > locationUpdateMethodThreshold) {
sch = Executors.newScheduledThreadPool(1);
sch.scheduleAtFixedRate(periodicTask, intervalForLocationUpdates, intervalForLocationUpdates, TimeUnit.MILLISECONDS);
}
} else if (intent.getAction().equals(Constants.ACTION.STARTLOCATIONREPEAT_ACTION)) {
if (!currentlyProcessingLocation) {
Log.i(TAG, "run: curt");
checkLocationSettings();
currentlyProcessingLocation = true;
mGoogleApiClient.connect();
}
} else if (intent.getAction().equals(Constants.ACTION.STOPFOREGROUND_ACTION)) {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, LocationService.this);
mGoogleApiClient.disconnect();
}
if (sch != null) {
sch.shutdownNow();
}
stopForeground(true);
stopSelf();
toastHandler("Tracking Stopped!");
}
}
}
void toastHandler(final String msg) {
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
public void run() {
Toast.makeText(LocationService.this, msg, Toast.LENGTH_SHORT).show();
}
});
}
}