服务无法在持续的后台位置跟踪上运行
Posted
技术标签:
【中文标题】服务无法在持续的后台位置跟踪上运行【英文标题】:Service doesn't run on continuous background location tracking 【发布时间】:2018-10-31 20:39:24 【问题描述】:我想在用户关闭应用后持续跟踪用户位置。该服务不断将位置存储在 DB 上,并且 wakefulintent 启动一个 timertask 以将其上传到服务器。我用过
LocationServices.FusedLocationApi.requestLocationUpdates(Utils.googleApiClient,
mlocationrequest, this);
在服务上。我已将清单上的服务声明为
<service
android:name="com.projest.services.BackgroundService"
android:enabled="true"
android:process=":Background">
</service>
并在我的主要活动中调用 servicew 使用
Intent service = new Intent(this, BackgroundService.class);
startService(service);
但服务不工作。我看不到日志。
public class BackgroundService extends Service implements LocationListener
public static final String TAG = "BackgroundService";
Context context;
LocationRequest mlocationrequest;
private static int UPDATE_INTERVAL = 10000; // 10 sec
private static int FATEST_INTERVAL = 5000; // 5 sec
public BackgroundService(Context context)
this.context = context;
public BackgroundService()
public void onCreate()
try
super.onCreate();
if(Utils.DEBUG)Log.d(TAG,"inside onCreate");
catch(Exception e)
if(Utils.DEBUG)Log.d(TAG,"problem oncreate");
public int onStartCommand()
if(Utils.DEBUG)Log.d(TAG,"inside onStartCommand");
if(!Utils.startGpsTracker)
Utils.startGpsTracker=true;
toggleGPS(true);
buildGoogleApiClient();
Utils.googleApiClient.connect();
if (Utils.googleApiClient.isConnected())
startLocationUpdates();
return START_STICKY;
public void onConnected(Bundle connectionHint)
Log.i(TAG, "Connected to GoogleApiClient");
if (Utils.latestLocation == null)
Utils.latestLocation = LocationServices.FusedLocationApi.getLastLocation(Utils.googleApiClient);
if(Utils.DEBUG)Log.d(TAG,"inside onconnected");
try
storeGpsinDb();
if(Utils.DEBUG)Log.d(TAG,"trouble opening storeGPS");
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
startLocationUpdates();
private void startLocationUpdates()
// TODO Auto-generated method stub
try
if (Utils.googleApiClient.isConnected())
LocationServices.FusedLocationApi.requestLocationUpdates(Utils.googleApiClient, mlocationrequest, this);
if(Utils.DEBUG)Log.d(TAG,"inside startlocationupdates");
catch (SecurityException ex)
@Override
public void onLocationChanged(Location location)
Utils.latestLocation = location;
try
storeGpsinDb();
if(Utils.DEBUG)Log.d(TAG,"inside onlocationchanged");
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
protected synchronized void buildGoogleApiClient()
if (Utils.googleApiClient == null)
Utils.googleApiClient = new GoogleApiClient.Builder(this.context).addApi(LocationServices.API).build();
if(Utils.DEBUG)Log.d(TAG,"googleAPIclient");
createLocationRequest();
private void createLocationRequest()
// TODO Auto-generated method stub
mlocationrequest = new LocationRequest();
mlocationrequest.setInterval(UPDATE_INTERVAL);
mlocationrequest.setFastestInterval(FATEST_INTERVAL);
mlocationrequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if(Utils.DEBUG)Log.d(TAG,"inside createlocationrequest");
public void onConnectionSuspended(int cause)
Utils.googleApiClient.connect();
if(Utils.DEBUG)Log.d(TAG,"insise connectionsuspended");
@Override
public void onDestroy()
if(Utils.DEBUG)Log.d(TAG,"inside onDestroy");
stopLocationUpdates();
Utils.googleApiClient.disconnect();
super.onDestroy();
protected void stopLocationUpdates()
if (Utils.googleApiClient.isConnected())
LocationServices.FusedLocationApi.removeLocationUpdates(Utils.googleApiClient, this);
@Override
public IBinder onBind(Intent intent)
// TODO Auto-generated method stub
return null;
private void toggleGPS(boolean enable)
String provider = Settings.Secure.getString(context.getContentResolver(),Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
if(Utils.DEBUG)System.out.println("toggleGPS:" + provider);
if (provider.contains("gps") == enable)
if(Utils.DEBUG)System.out.println("toggleGPS:enable true");
return; // the GPS is already in the requested state
if(Utils.DEBUG)System.out.println("toggleGPS:enable false");
final Intent poke = new Intent();
poke.setClassName("com.android.settings",
"com.android.settings.widget.SettingsAppWidgetProvider");
poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
poke.setData(Uri.parse("3"));
this.context.sendBroadcast(poke);
private void storeGpsinDb() throws IOException
if (!(Utils.latestLocation==null))
else
//
我犯了什么错误 我正在为此工作两周。请帮助我。
【问题讨论】:
【参考方案1】:您需要在清单中定义 android:stopWithTask="false"。
如果您的应用从最近的应用中删除,则从服务运行的进程(线程)将停止工作。为确保您的进程(线程)始终处于运行状态,您必须重写 onTaskRemoved() 方法并添加代码以重新启动任务,如下所示。
@Override
public void onTaskRemoved(Intent rootIntent)
Intent restartServiceTask = new Intent(getApplicationContext(),this.getClass());
restartServiceTask.setPackage(getPackageName());
PendingIntent restartPendingIntent =PendingIntent.getService(getApplicationContext(), 1,restartServiceTask, PendingIntent.FLAG_ONE_SHOT);
AlarmManager myAlarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
myAlarmService.set(
AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 1000,
restartPendingIntent);
super.onTaskRemoved(rootIntent);
【讨论】:
以上是关于服务无法在持续的后台位置跟踪上运行的主要内容,如果未能解决你的问题,请参考以下文章
当我“关闭” UISwitch 时,后台位置服务跟踪不会停止
当应用程序未在后台运行时,使用 startmonitoringsignfiicantlocationchanges 跟踪设备位置