设备重启后,Geofences是否在android中保持活动状态

时间:2013-11-19 19:05:09

标签: android google-play-services geofencing android-geofence location-client

我正在编写一个应用程序,当有人在正在安装的应用程序的生命周期内进入/退出多个站点时,需要使用地理围栏。

我的地理围栏实现(非常类似于下面的第二个链接)在我第一次安装应用程序时都能正常工作,无论是在移入/移出地理围栏时还是在使用模拟位置进行模拟时,都会重新启动设备。

在重新启动时,模拟位置或实际上物理移入和移出地理围栏似乎都会触发事件并将未决意图发送到我的广播接收器。

我已经查看了以下三个链接,并且还阅读了相当多的文档,但我无法找到一个明确的答案,直接说注册地理围栏持续存在或重启后不会持续存在。

这些是我在堆栈溢出时查看的链接: Are Android geofences surviving a reboot?

Android Geofence eventually stop getting transition intents

Do Android Geofences remain active until removed/expired or only until my PendingIntent is launched

如果有人碰巧知道他们是否坚持重新启动后的答案,或者如果他们没有解决问题,那么我们将非常感激!我最近的希望是为BOOT_COMPLETED创建一个监听器,并在启动时重新注册它们,但是如果绝对必要的话,id更喜欢这样做。

提前多多感谢!

编辑:虽然我没有找到明确的(书面)答案,但我很确定TonyC先生发布的内容是正确的,并选择了该解决方案。非常感谢TonyC!

如果有人想看到我的解决方案,我会在设备启动时监听启动完成操作,然后重新注册我需要的所有地理围栏。

这是清单:

<!-- Listen for the device starting up -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

<receiver android:name="com.YOUR.PACKAGE.geofence.BootCompleteReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

然后为它创建一个广播接收器,它将在启动时重新注册地理围栏:

package com.YOUR.PACKAGE.geofence;

import android.app.PendingIntent.CanceledException;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.Geofence;

public class BootCompleteReceiver extends WakefulBroadcastReceiver
{
    private static final String TAG = "BootCompleteReceiver";

    @Override
    public void onReceive(Context context, Intent intent)
    {
        //Do what you want/Register Geofences
    }
}

值得注意的是,如果您在启动时处于地理围栏中,那么一旦注册了地理围栏,这通常会触发地理围栏的未决意图。

因此,例如,如果地理围栏启动应用程序,那么当您启动恰好位于地理围栏中的设备时,一旦启动完整广播接收器已注册地理围栏并且位置服务已经工作,它也将打开应用程序你在哪里。

希望这对某人有所帮助。

2 个答案:

答案 0 :(得分:13)

根据我的经验,地理围栏不会重启。我按照你的建议使用BOOT_COMPLETED接收器。它工作正常。

答案 1 :(得分:8)

Geofences在重新启动后无法生存。在其他情况下,您也必须重新注册地理围栏。

除了BOOT_COMPLETED之外,Re-register geofences only when required文档还会调出几种情况,您需要重新注册地理围栏。遗憾的是,这是模糊和不完整的。

让我们逐点考虑从Android O开始强加的新background execution limits

  • 重启设备

可以通过将以下内容添加到您的intent-filter来处理此问题,因为它们是exempted from the implicit broadcast ban

<action android:name="android.intent.action.BOOT_COMPLETED" />

然后,确保将以下权限添加到清单中:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

您可能希望捕获Android N中引入的较新LOCKED_BOOT_COMPLETED意图:

<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />

但是,如果你这样做,你还需要用android:directBootAware=”true”标记你的接收者。这introduces ramifications for your app。即,您访问的任何基于文件的数据必须使用受设备保护的存储来完成。它的长短是,如果您在设备启动到锁定屏幕时不需要通知,请不要使用LOCKED_BOOT_COMPLETED。

  • 该应用已卸载并重新安装

同样,我们在这里很幸运,因为你可以使用这个明确的意图:

<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
  • 应用的数据已清除

这是我不知道的地方。有一个ACTION_PACKAGE_DATA_CLEARED免于隐式广播禁令,但只有在清除了另一个数据包的数据时才会被触发。我已经尝试了这一点,并且可以确认当您自己的应用数据被清除时,您不会被呼叫。

  • Google Play服务数据已清除

这可以通过将以下内容添加到您的接收器来处理:

<intent-filter>
    <!-- Used to watch for Google Play Services data cleared -->
    <action android:name="android.intent.action.PACKAGE_DATA_CLEARED" />
    <data android:scheme="package" android:sspPrefix="com.google.android.gms"/>
</intent-filter>

然后将以下代码添加到BroadcastReceiver的onReceive方法中:

String action = intent.getAction();
if (TextUtils.equals(Intent.ACTION_PACKAGE_DATA_CLEARED, action)) {
    Uri uri = intent.getData();
    if (uri.toString().equals("package:com.google.android.gms")) {
        // Code here to handle Google Play services data cleared
    }
}

这是Android通过地理围栏API通知您位置服务不再可用的方式,并通过发送错误和状态代码为GeofencingEventGEOFENCE_NOT_AVAILABLE来表示。< / p>

但是,只需遵循地理围栏文档的模糊建议,您就会相信您可以在此时重新注册地理围栏。这可能很糟糕,因为位置服务可能仍然被禁用,这样做会导致更多GEOFENCE_NOT_AVAILABLE s。我们需要的是一个用来判断何时切换位置服务的钩子。

直到Android O,为android.location.MODE_CHANGED_ACTION注册BroadcastReceiver会给你这个钩子。在Android O及更高版本中,此隐式意图被禁止,您的BroadcastReceiver不再被调用,因此需要另一个钩子。

对于Android O及更高版本,我发现使用JobSchedulerJobInfo.Builder.addTriggerContentUri一起监控 Settings.Secure.LOCATION_PROVIDERS_ALLOWED URI可用于此目的,如果当前正在运行以调用您的JobService,它甚至会启动您的应用。这种方法需要API&gt; = 24.我已经验证这是有效的,包括Android P(API 28)。

使用JobScheduler方法的一些注意事项:

  1. 您的应用可能无法立即得到通知,但在我的测试中,它会在几分钟内得到通知。
  2. LOCATION_PROVIDERS_ALLOWED已弃用,可在未来的Android版本中删除。
  3. 因此,如果您使用minApi版本24,那么您可以使用JobScheduler / JobService来获取Settings.Secure.LOCATION_PROVIDERS_ALLOWED钩子。

    但是,如果您不想放弃10%的用户群(as of this writing, KitKat (API 19) garners 9.1% of Android's active user base)并且需要较低的minApi,那么您需要同时拥有BroadcastReceiver和JobService。 / p>