我创建了一个示例前台服务,以检查是否可以在每15分钟或30分钟后从后台获取位置。随着打盹模式的介绍,报警管理器在准确的时间不起作用。
在前台服务中,我尝试使用处理程序后延迟,但这也不起作用,因为我得到的间隔最多3小时。在下面的代码中我使用了ScheduledThreadPoolExecutor,它表现得更糟。我迟到了12个小时。我已经在Android 6.0上测试了这个。
有人可以为此建议解决这个问题吗?
package com.hitec16.foregroundservicetest;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import java.text.DateFormat;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class MyService extends Service
implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = "MyService";
private static final long INTERVAL = 1000 * 10;
private static final long FASTEST_INTERVAL = 1000 * 5;
private static final long WAIT_INTERVAL = 1000 * 30;
private ScheduledThreadPoolExecutor mExecutor;
private int mCounter = 0;
private FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mCurrentLocation;
private String mLastUpdateTime;
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
// throw new UnsupportedOperationException("Not yet implemented");
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
onStart_(intent, flags, startId);
Looper.loop();
}
});
thread.start();
// onStart_(intent,flags,startId);
return START_STICKY;
}
private void onStart_(Intent intent, int flags, int startId) {
if (intent.getAction().equals(Constants.STARTFOREGROUND_ACTION)) {
Logger.d("Received Start Foreground Intent ");
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
connectToGoogleApi();
showNotification();
Toast.makeText(getApplicationContext(), "Service Started!", Toast.LENGTH_SHORT).show();
Logger.d("work finished");
// fetchLocationAgain();
mExecutor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(2);
mExecutor.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
try {
startLocationUpdates();
} catch (Exception e) {
Log.d(getClass().getSimpleName(), "Exception caught: " + e.getMessage());
}
Log.d("Test", "test");
}
}, 30, 60 * 15, TimeUnit.SECONDS);
}
}
private void showNotification() {
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setAction(Constants.MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("Fused Location Service")
.setTicker("ticker text")
.setContentText("My Location")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.setContentIntent(pendingIntent)
.setOngoing(true)
.build();
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,
notification);
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, MyService.this);
mCounter = 0;
Logger.d("Location update stopped .......................");
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Logger.d("onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
try {
startLocationUpdates();
} catch (Exception e) {
Log.d(getClass().getSimpleName(), "Exception caught: " + e.getMessage());
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Logger.d("Connection failed: " + connectionResult.toString());
}
@Override
public void onLocationChanged(Location location) {
if (mCounter < 3) {
Log.d(getClass().getSimpleName(), "returned....");
mCounter++;
return;
}
Logger.d("Firing onLocationChanged..............................................");
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
Logger.d("Location latitude and longitude :" + location.getLatitude() + " ," + location.getLongitude()
+ " , Accuracy : " + location.getAccuracy() + ", location provider : " + location.getProvider() + "Time : " + mLastUpdateTime);
stopLocationUpdates();
}
protected void startLocationUpdates() throws Exception {
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this, Looper.getMainLooper());
Logger.d("Location update started ..............: ");
}
@Override
public void onDestroy() {
disconnectFromGoogleApi();
Log.d(getClass().getSimpleName(), "on destroy called");
mExecutor.shutdown();
super.onDestroy();
}
private void connectToGoogleApi() {
Logger.d("connectToGoogleApi fired ..............");
mGoogleApiClient.connect();
}
private void disconnectFromGoogleApi() {
Logger.d("disConnectFromGoogleApi fired ..............");
mGoogleApiClient.disconnect();
}
}