几个小时后融合位置停止发送更新

Fused location stops sending updates after several hours

如果我让应用程序打开几个小时,融合位置将停止发送更新...

我正在创建具有高优先级的位置请求,这里是代码:

LocationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setExpirationDuration(TimeUnit.SECONDS.toMillis(LOCATION_TIMEOUT_IN_SECONDS))
                .setInterval(LOCATION_UPDATE_INTERVAL);

这是客户端和回调:

LocationCallback mLocationCallback = new LocationCallback() {
        @Override
        public void onLocationAvailability(LocationAvailability locationAvailability) {
            super.onLocationAvailability(locationAvailability);
        }

        @Override
        public void onLocationResult(LocationResult locationResult) {
            super.onLocationResult(locationResult);
            //Update location
        }
    };
    mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
    mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest, mLocationCallback, null);

LOCATION_TIMEOUT_IN_SECONDS 是 5 秒,但更新并不总是 运行,当我的应用程序需要位置时,我手动停止并启动它。就像是 documented .

如果应用程序 运行 一两个小时一切正常,但如果我长时间打开它,它就会停止工作....

我在单击按钮时从 Activity 请求了位置更新,10 秒后,我手动停止了位置更新...如果我整夜离开它,这意味着 Activity 整晚都在运行...之后,当我再次请求位置更新时,它不会出现...

有什么解决办法或想法吗?

setExpirationDuration(long millis)

来自文档:

Set the duration of this request, in milliseconds.

The duration begins immediately (and not when the request is passed to the location client), so call this method again if the request is re-used at a later time.

The location client will automatically stop updates after the request expires.

The duration includes suspend time. Values less than 0 are allowed, but indicate that the request has already expired.

如果您想永远接收位置更新,请将其删除或设置适当的时间。

这是我的应用程序 class :

public class MyApplication extends Application  {

  public static boolean isActivityVisible() {
   return activityVisible;
 }

 public static void setVisibilityTrue() {
  activityVisible = true;
 }

这是我的 baseActivity Class :

 public static void activityResumed() {
 boolean isScreenOn = true;
 // isScreenOn() method is deprecated API level 21. You should use 
 isInteractive instead:
 PowerManager pm = (PowerManager) 
 MyApplication.getInstance().getSystemService(Context.POWER_SERVICE);
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
     isScreenOn = pm.isInteractive();
 } else {
    isScreenOn = pm.isScreenOn();
 }
 if (isScreenOn) {
    activityVisible = true;
 }

}

 public static void activityPaused() {
 boolean isScreenOn = true;
 PowerManager pm = (PowerManager) 
MyApplication.getInstance().getSystemService(Context.POWER_SERVICE);
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
     isScreenOn = pm.isInteractive();
 } else {
     isScreenOn = pm.isScreenOn();
 }
 if (isScreenOn) {
     activityVisible = false;
 }

}
private static boolean activityVisible;

}

当应用程序在后台时,我们将其置于前台,每 30 秒使用一个计时器,我们检查应用程序屏幕是否已锁定,如果已锁定,我们将打开应用程序:private void bringApplicationToFront(Context context) { /** * check if motitor screen is Off/On * */ boolean isScreenOn = true; PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { isScreenOn = pm.isInteractive(); } else { isScreenOn = pm.isScreenOn(); } if (!isScreenOn) { /** * check if app is fore/back ground * */ boolean isInForeBackground = false; try { isInForeBackground = MyApplication.isActivityVisible(); } catch (Exception e) { e.printStackTrace(); } if (!isInForeBackground) { Intent notificationIntent = new Intent(context, ActivitySplash.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); try { pendingIntent.send(); } catch (PendingIntent.CanceledException e) { e.printStackTrace(); } } } }

我认为如果应用程序进入前台,它的优先级很高,那么它可以一直使用 gps。

棘手的部分是当应用程序在后台并且屏幕被锁定时,在重新打开应用程序(将其带到前台)后调用 onPause() 意味着 activityVisible 设置为 false(意味着不可见,这是不正确的) ,实际上它是正确的,但它不是我想要的,为了解决这个问题,我从不让 activityVisible 在屏幕锁定时设置,当应用程序在启动时重新打开时,我将 activityVisible 设置为 true。

希望对您有所帮助...