Android:LocationManager服务在设置为网络提供商时停止更新

Android:LocationManager服务在设置为网络提供商时停止更新,android,service,location,locationmanager,Android,Service,Location,Locationmanager,对,情况如下, 我们开发了一款应用程序,每5-10分钟检查一次用户的位置,查看特定位置的内容。为了做到这一点,我创建了一个服务,以坚持到后台(这样即使应用程序不直接在前台也可以更新),其中创建了LocationController来检查最新的已知位置。完成后,它会进行清理,并将位置发送到数据库(这是此概念的必要条件) 这一切都很好,只要我检查与GPS_供应商的位置。然而,当我将它切换到网络提供商时,它可能会在完全死亡之前再次检查位置 我尝试了多个选项来防止这个问题,但是当我交换1设置时,更新服务

对,情况如下,

我们开发了一款应用程序,每5-10分钟检查一次用户的位置,查看特定位置的内容。为了做到这一点,我创建了一个服务,以坚持到后台(这样即使应用程序不直接在前台也可以更新),其中创建了LocationController来检查最新的已知位置。完成后,它会进行清理,并将位置发送到数据库(这是此概念的必要条件)

这一切都很好,只要我检查与GPS_供应商的位置。然而,当我将它切换到网络提供商时,它可能会在完全死亡之前再次检查位置

我尝试了多个选项来防止这个问题,但是当我交换1设置时,更新服务似乎没有任何效果

以下是与服务相关的几个片段:

更新服务:

 @Override
public void onCreate() {
    super.onCreate();
    Log.d("Debug", "Created service");
    PowerManager mgr = (PowerManager)getSystemService(Context.POWER_SERVICE);
    wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
    wakeLock.acquire();
    IntentFilter filter = new IntentFilter();
    filter.addAction(UPDATE_ACTION);

}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    Log.d("Starting", "Starting Service");

    mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    mAlarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);

    Intent i = new Intent(UPDATE_ACTION);
    alarmManagerPendingIntent = PendingIntent.getBroadcast(this, 0, i, 0);
    alarmManagerPendingIntent.cancel();
    mAlarmManager.cancel(alarmManagerPendingIntent);

    mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                AlarmManager.INTERVAL_FIFTEEN_MINUTES,
                AlarmManager.INTERVAL_FIFTEEN_MINUTES, 
                alarmManagerPendingIntent);

    mLocationController = new LocationController(this, this);

    updateHandler = new Handler();

    return START_STICKY;
}
位置控制器:

private LocationListener locationListener = new LocationListener() {
    private boolean didSendLocation;
    public void onLocationChanged(Location location) {
        mLastLocation = location;
        mCallback.locationUpdate(location,false);
        didSendLocation = true;
    }

    public void onStatusChanged(String provider, int status, Bundle extras) {
        Log.d("Debug", "Status changed: "+status);
        Location _lastLocation = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        Log.d("Debug", "Last location: "+_lastLocation); 
        if(!didSendLocation)
        {

            mCallback.locationUpdate(_lastLocation,false);
        }
        didSendLocation = false;
    }

    public void onProviderEnabled(String provider) {
        Log.d("Debug", "Provider Enabled");
    }

    public void onProviderDisabled(String provider) {
        Log.d("Debug", "Provider disabled");
    }
};

public LocationController(Context mContext, LocationControllerCallback callback) {
    this.mContext = mContext;
    mCallback = callback;
    Log.d("Debug", "Created LocationController");
    mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
    mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 300000, 100, locationListener);
    mLastLocation = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

    mCallback.locationUpdate(mLastLocation,true);
}
因此,代码按现在的方式工作,但当我交换时:

mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 300000, 100, locationListener);


它将不再更新。有什么想法吗?

当您使用此功能获取位置更新时:

mLocationManager.requestLocationUpdates(...)
您不需要
AlarmManager
方法,因为
requestLocationUpdates
方法的第一个参数已经充当“计时器”。有关更多信息,请参阅

此外,您可能需要在AndroidManifest.xml文件中包含以下指令:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.CONTROL_LOCATION_UPDATES"/>

然后,在活动(MainActivity或项目中的另一个活动)的
onResume
方法中启动上述服务,并在同一活动的
onPause
方法中暂停服务。

如果特定于网络提供商,您可能会看到以下错误:

最初的错误报告包括三星Galaxy S3作为受影响的设备

为了帮助排除故障,您可能还希望尝试在(完全公开-其我的应用程序)中选择网络提供商,以查看此应用程序是否表现出相同的行为。如果是这样的话,很可能是设备的问题


如果您确定您看到了上述问题,请确保在问题页面上加上星号,如果您希望看到它得到修复。

我通过切换到Google Play Fused Location提供商解决了问题。关于这一点的更详细的帖子可以在这里找到:


遗憾的是,标准网络提供商在更新方面似乎太不可靠了,从8分钟内的更新到新更新发送到应用程序前的几个小时。

locationcontroller使用LocationControllerCallback引用更新服务,所以我相信我以前尝试过,但由于无法进行回调,它最终停止了工作。至于清单,粗略和精细的位置已经在那里了,但我会尝试添加控制位置更新。更新1:当应用程序在后台时(并且可能被Android杀死),这还会允许位置更新继续吗?该服务的运行正是出于这个原因,因为该应用程序可以在外出之初使用,并且在您的位置上仍然是最新的,比方说,3小时后,您的手机就在您的口袋里。您可能需要更改为
服务。start\u STICKY在您的情况下。但是尝试一下
服务。在进行更改之前,先启动\u NOT \u STICKY
,看看它是否满足您的要求。嗯,这种情况现在正在使用,但遗憾的是似乎并没有解决问题。使用NETWORK_PROVIDER时,它似乎只更新1到2次,但使用GPS_PROVIDER时,它仍然有效:(在真实设备或AVD上不起作用?请详细说明。请注意,如果使用
LocationManager.NETWORK_PROVIDER
,则可能需要启用“使用无线网络”选项。否则,如果使用
LocationManager.GPS_PROVIDER
,则启用“使用GPS卫星”选项。这些选项可在设置|位置服务中找到。)你的Android设备上有u个选项。谢谢,我已经检查过了,这不是设备问题。所以至少这意味着我可以看到一些应该可以解决的问题:p
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.CONTROL_LOCATION_UPDATES"/>
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);
    this.mLocationController = new LocationController(this);
    return Service.START_NOT_STICKY;
}