一次性权限导致后台计划的作业和警报被取消
One-time permissions causing background scheduled jobs and alarms to be cancelled
我们开发了一个 Android SDK,并且在测试 Android 11 Beta 时,我们发现了一个似乎尚未报告的问题。
在 Android11 中,位置、麦克风和相机权限引入了新的一次性权限。使用此选项,一旦用户离开应用程序,权限就会被撤销(更多详细信息可以找到 here)。
问题是,当应用程序不再在前台运行一小段时间后(不需要终止应用程序,只需最小化就足够了),所有未来预定的警报或作业都将被删除,因为如果应用程序被强制终止。 只有在获得此级别许可的情况下才会发生这种情况。 拒绝或提供其他级别会按预期保留先前安排的警报或作业。 我们在 Beta 3 版本中,在具有 RPB3.200720.005 版本号的 Pixel 2 模拟器中重现了这一点。在此 repo 中,您可以找到用于重现错误的示例应用程序。
这个 activity 应用程序安排闹钟在接下来的五分钟内响起,并在 5-6 分钟内触发一个作业。 屏幕上有三个按钮,每个按钮都会触发相应的权限请求。 JobService 和 BroadcastReceiver 类 仅记录它们已被触发。 可以通过以下步骤重现该情况:
- 无论何时启动应用程序,都可以运行
adb shell dumpsys alarm | grep com.example.permissions.app
和adb shell dumpsys jobscheduler | grep com.example.permissions.app
来查看闹钟和作业是否已安排; - 单击任一按钮并授予一次性权限级别;
- 最小化应用程序(您可以转到主屏幕或打开其他应用程序);
- 大约一分钟后,运行
adb shell dumpsys alarm | grep com.example.permissions.app
和adb shell dumpsys jobscheduler | grep com.example.permissions.app
。警报和作业将不再出现; - 等待作业和警报的原始预定时间(对系统延迟宽容)将表明它们不会被触发。
大家遇到过类似的情况吗?我们的直觉是,要撤销一次性权限,应用程序进程会以某种方式被杀死,从而导致这些副作用。 我们还在 Android Issue Tracker 上提交了一个问题,如果 Google 回答了这个问题,我们将保持这个 post 更新。
问题是 'solved'。问题实际上是 Android Studio 在关闭应用程序后撤销权限时调用强制关闭。
实际 Google 的响应:
Thank you very much for raising this issue, and providing sample code to reproduce it. After investigating further, we discovered that this is due to an interaction between Android Studio and apps launched via the "Run" command.
Specifically, when Android revokes an app's permission, it kills that app's process. We found that Android Studio sends a force-stop command via adb when it observes the app it launched is no longer running.
If the app is started via the launcher (including in an emulator that's connected to Android Studio), the app is not force-stopped, and the alarm and job both run as expected.
所以除了在开发阶段,它不会引起其他问题。有关详细信息,请查看问题中链接的 Android 问题跟踪器。
我知道我的问题不完全是这个问题,但我在 android 11 in google 地图中单击此一次性权限时也遇到了这个问题。我注意到如果您在后台离开您的应用程序 1 分钟然后返回,应用程序进程将被终止。
我在 viewpager 中有 2 个 SupportMapFragment 并在 TabLayout 中连接,每次发生这种情况时,都会重新创建视图,但是没有正确重新创建位于 viewpager 当前位置的片段。
对于同样遇到此问题的人,您必须更改流程并仅使用 1 个 SupportMapFragment 而不是两个。这样,您的地图片段将被正确地重新创建。我只是根据选项卡当前位置处理地图状态和标记