在启动某些活动之前,小部件无法在 Android 11 上的设备启动时启动服务

Posted

技术标签:

【中文标题】在启动某些活动之前,小部件无法在 Android 11 上的设备启动时启动服务【英文标题】:Widget can't start a service on device boot on Android 11 until some activity is launched 【发布时间】:2021-08-06 20:48:49 【问题描述】:
val startServiceIntent = TestService.getServiceIntent(context).let 
    PendingIntent.getService(context, 0, it, PendingIntent.FLAG_UPDATE_CURRENT)

val views = RemoteViews(context.packageName, R.layout.layout_app_widget).apply 
    setOnClickPendingIntent(R.id.start_service_btn, startServiceIntent) // doesn't work on boot device
    setOnClickPendingIntent(R.id.start_activity_btn, startActivityIntent) // works fine

appWidgetManager.updateAppWidget(appWidgetId, views)

如何对待这种行为?我如何至少向用户显示一条消息,即在他启动应用程序(使其可见)或在此设备会话期间启动活动之前,无法从小部件启动服务?

因为现在当我按下按钮启动服务时什么都没有发生,直到我至少启动一次应用程序

android 11 上是否有任何方法可以检查我们是否可以从后台/小部件启动前台服务、相机等?如何确定用户在设备当前会话中至少启动了一次应用活动?

【问题讨论】:

你有tried PendingIntent.getForegroundService()吗? @CommonsWare 谢谢,它有效。很棒的是,我们可以从小部件开始在前台服务中使用 Android 11 上的摄像头和麦克风,而无需在设备启动后启动应用程序(活动) 【参考方案1】:

钻研Android OS的源码后,发现了以下方法来检查摄像头是否受限:

@RequiresApi(Build.VERSION_CODES.Q)
internal fun AppOpsManager.isCameraAllowedForPackage(packageName: String): Boolean 
    val res = unsafeCheckOpNoThrow(
        AppOpsManager.OPSTR_CAMERA,
        android.os.Process.myUid(),
        packageName
    )
    return res == AppOpsManager.MODE_ALLOWED

【讨论】:

谢谢。我也需要它。【参考方案2】:

根据@CommonsWare 评论,我需要使用PendingIntent.getForegroundService() 而不是PendingIntent.getService()

【讨论】:

以上是关于在启动某些活动之前,小部件无法在 Android 11 上的设备启动时启动服务的主要内容,如果未能解决你的问题,请参考以下文章

运行应用小部件 - 无法识别启动活动

Android Widget:在将小部件添加到屏幕之前显示配置活动

通过单击整个小部件来启动活动在 Android Studio 中不起作用

当小部件具有配置活动时,无法从小部件启动活动

android 小部件开始一个新的活动

为Android中的小部件启用小部件设置按钮?