Android 11 - 按下主页按钮时触发前台服务 onTaskRemoved

Android 11 - foregroundService's onTaskRemoved is trigged when home button pressed

我在 Pixel 4XL (Android 11) 上看到一些奇怪的行为。 我的前台服务的 onTaskRemoved 被意外调用。 这不会发生在任何其他设备上,但我没有任何其他 Android 11 设备,模拟器无法执行 BLE。

我的应用程序使用正在进行的 BLE 连接与另一个非 android 设备通信。 前台服务用于确保程序保持活动状态以接收来自设备的 BLE 通信。

它并不总是发生,但在大多数情况下(75% 的时间)按下主页(在 Pixel 4XL 上从屏幕底部向上滑动)后,这将导致前台服务的 onTaskRemoved 被调用。

在我的应用程序中打开一个不同的 activity(即 MainActivity 以外的 activity)几乎可以保证会发生这种情况。

从通知栏打开设置然后滑动主页仍然会触发这种情况,所以我不会不小心杀死应用程序,因为我在设置应用程序处于焦点时向上滑动。

根据我的理解,只有当用户通过在任务切换器中滑动来终止应用程序时,才会触发此方法。

如果我回到任务切换器,在服务被终止后,我的应用程序仍然可用并显示最后 activity 打开的状态。切换到它会恢复到正确的位置,因此应用程序本身一定没有终止。 phone 已插入充电中,因此它不应该和 doze/sleeping 正常工作。 这可能会在启动应用程序后 60 秒内发生,而不是 30 分钟。

这到底是怎么回事? 我唯一能想到的是,出于某种原因,它不被视为前台服务。在 onTaskRemoved 期间或前后 logcat 中没有错误。我不会在代码中的任何地方自己调用 onTaskRemoved。

我试过使用 dumpsys in this post,但它似乎有所不同,我找不到任何提到的参考资料。

通知本身是这样列出的:

$ adb shell dumpsys activity services | grep foreground
isForeground=true foregroundId=13459 foregroundNoti=Notification(channel=xxxService shortcut=null contentView=null vibrate=null sound=null tick defaults=0x0 flags=0x62 color=0x00000000 actions=1 vis=PRIVATE)

是的,我在清单中设置了前台权限:

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

BLEService onCreate 方法(删除了一些不相关的):

@Override
public void onCreate()
{
    BLEManager.getInstance(getApplicationContext());

    startForeground(
            NotificationHandler.NOTIFICATION_BTCONNECTION_ID,
            NotificationHandler.getInstance(getApplicationContext()).createConnectionNotification(getApplicationContext(), MainActivity.class, R.drawable.navigation_tab, R.drawable.baseline_clear_black_24, getString(R.string.myDevice_text_disconnect), getString(R.string.app_name), getString(R.string.bleService_text_connected), getString(R.string.bleService_text_connected))
    );
}

通知渠道:

        NotificationChannel serviceChannel;
        serviceChannel = new NotificationChannel(
                NOTIFICATION_SERVICE_CHANNEL_ID,
                serviceNotificationChannelLabel,
                NotificationManager.IMPORTANCE_HIGH
        );

        serviceChannel.setDescription(serviceNotificationChannelDescription);
        serviceChannel.enableLights(false);
        serviceChannel.setShowBadge(false);
        serviceChannel.enableVibration(false);

        mNotificationManager.createNotificationChannel(serviceChannel);

通知:

    NotificationCompat.Builder nBuilder = new NotificationCompat.Builder(context, NOTIFICATION_SERVICE_CHANNEL_ID)
            .setSmallIcon(icon)
            .setContentTitle(contentTitle) 
            .setContentText(contentText) 
            .setContentIntent(pLaunchIntent)
            .setTicker(tickerText) 
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setOngoing(true)
            .setAutoCancel(false)
            .addAction(icButton1, button1Text, actionPendingIntent); 

    return nBuilder.build();

对我来说,将 activity 启动模式从 singleInstance 更改为解决了问题。

改变

        android:launchMode="singleInstance"

        android:launchMode="singleTop"

或完全删除它

显然,使用 singleInstance 是有正当理由的,这仍然是意外行为,但目前它是一个有效的解决方法。