Android:LocationManager服务在设置为NETWORK_PROVIDER时停止更新

时间:2014-04-14 14:01:16

标签: android service location locationmanager

对,情况如下;

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

这一切都正常,只要我用GPS_PROVIDER检查位置。但是,当我将其切换到NETWORK_PROVIDER时,它可能会在完全死亡之前再次检查位置。

我已经尝试了多种方法来防止出现这个问题,但是当我交换1个设置时似乎没有任何东西可以用于更新服务。

以下是一些与服务相关的摘要:

UpdateService:

 @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;
}

LocationController:

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(LocationManager.NETWORK_PROVIDER, 300000, 100, locationListener);

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

3 个答案:

答案 0 :(得分:0)

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

mLocationManager.requestLocationUpdates(...)

您不需要AlarmManager方法,因为requestLocationUpdates方法的第一个参数已经充当"计时器"。有关详细信息,请参阅here

此外,您可能需要在 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"/>

如果没有这些权限,requestLocationUpdates方法可能无法正常工作,无论您使用哪个提供商。

更新1:

我会在服务中初始化您的LocationController课程,例如:

@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;
}

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

答案 1 :(得分:0)

如果它特定于NETWORK_PROVIDER,您可能会看到此错误: https://code.google.com/p/android/issues/detail?id=57707

原始错误报告包括三星Galaxy S3作为受影响的设备。

为了帮助您排查问题 - 您可能还想尝试在GPS Benchmark app中选择NETWORK_PROVIDER(完全披露 - 我的应用),看看此应用是否表现出相同的行为。如果是这样,它可能是设备的问题。

如果您确定自己发现了上述问题,请务必在问题页面上将其加注星号,如果您希望修复此问题。

答案 2 :(得分:0)

我已切换到Google Play Fused Location提供商解决了这个问题。有关此问题的更详细信息,请访问:https://stackoverflow.com/a/19282976/3532181

可悲的是,标准网络提供商在更新时似乎太不可靠,从8分钟内的更新到新的更新发送到应用程序之前的数小时。