服务无法在持续的后台位置跟踪上运行

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

【讨论】:

以上是关于服务无法在持续的后台位置跟踪上运行的主要内容,如果未能解决你的问题,请参考以下文章

ios12后台定位服务停止

应用程序在后台运行时进行位置跟踪

在后台永远运行Swift 2.0应用程序以更新服务器的位置

当我“关闭” UISwitch 时,后台位置服务跟踪不会停止

当应用程序未在后台运行时,使用 startmonitoringsignfiicantlocationchanges 跟踪设备位置

当应用程序在后台运行时无法找到位置更新