在Android Q中从接收器启动活动

5
我正在使用Android Q [beta 6]检查我的应用程序,以添加所有必需的更改,以与最新的操作系统完全兼容。然而,我发现我正在使用一个接收器从后台启动活动,并且由于最近实施的后台限制(https://developer.android.com/preview/privacy/background-activity-starts),该活动未被打开。
我尝试使用接收器上下文和应用程序上下文来启动活动,但在两种情况下,系统都会显示一个toast,说明无法从后台启动活动。
我在接收器上尝试的内容...
class MyReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context?, intent: Intent?) {
        context?.applicationContext?.let {
            it.startActivity(Intent(it, MyActivity::class.java).apply {
                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            })
            PushUtils.showReceiverCalledNotification(it)
        }
    }

我希望启动MyActivity并在接收器被调用时显示通知。但实际上,我能看到通知,但是Activity从未启动。这个功能非常重要,需要立即启动Activity,那么有没有一种方法可以从接收器继续启动Activity?

你尝试过使用 SYSTEM_ALERT_WINDOW 权限了吗? - Tanasis
是的,调用 startActivity 时遇到了相同的问题。 - user3429953
2个回答

4
非常重要的是立即启动功能,因此有一种方法可以从接收器继续启动该活动吗?
不好意思,没有。请使用高优先级通知,以便它以“悬浮式通知”模式出现。用户随后可以快速点击它以打开您的活动。

@commonsware 那闹钟/提醒应用程序怎么办?它们必须从后台启动活动以播放闹铃,通知在这里并不是真正的解决方案。 - qkx
@qkx:如果通知被触发时显示器关闭,则悬浮通知将直接通过全屏“意图”显示活动。如果显示器处于开启状态,则悬浮通知会显示一个气泡几秒钟,因为用户正在使用设备,打断他们的操作可能不安全。 - CommonsWare
那不是解决方案,警报不应该这样工作。警报应该是全屏活动,播放声音。所以现在无法再为Android制作闹钟应用程序了吗? - qkx
1
文档来看,如果用户授予了“在其他应用程序上显示”的权限,则该应用程序将免于限制。 - Jack
1
你好@AdesuyiAyodeji,由于新的后台限制,我无法打开一个Activity,但我可以构建一个全屏通知,它的工作方式与CommonsWare在评论中发布的完全相同。我按照这些步骤进行操作:https://dev59.com/dpfga4cB1Zd3GeqPA8vU#43830658,对我来说已经足够了... - user3429953
显示剩余3条评论

3

由于限制,您无法从后台启动活动。相反,您可以像CommonsWare建议的那样使用通知,并且在安卓开发者网站上也提出了类似的建议。

这里是官方文档,列出了什么情况下可以工作,什么情况下不行。

https://developer.android.com/guide/components/activities/background-starts

您可以使用类似以下代码的东西:

class MyReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        context ?: return
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            showNotification(context.applicationContext)
        } else {
            context.applicationContext.startActivity(Intent(context, MyActivity::class.java).apply {
                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            })
        }
        PushUtils.showReceiverCalledNotification(context)

    }

    private fun showNotification(context: Context) {
        val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager ?: return
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel("default", "default", NotificationManager.IMPORTANCE_DEFAULT)
            manager.createNotificationChannel(channel)
        }

        val intent = Intent(context, MyActivity::class.java).apply {
            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        }

        val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT)

        with(NotificationCompat.Builder(context, "default")) {
            setSmallIcon(R.drawable.ic_scan_colored)
            setContentTitle("Custom Title")
            setContentText("Tap to start the application")
            setContentIntent(pendingIntent)
            setAutoCancel(true)
            manager.notify(87, build())
        }
    }
}

非常感谢提供示例代码。是的,我认为这是最佳选择,因为有了新的限制(如果无法复制当前行为,那么这也是我想要做的)。 - user3429953
3
WhatsApp是如何运作的?当我的应用关闭时,我怎么会接到电话? - Rahul Giradkar
想一想,我怎么才能从通知中显示短信弹窗?!! - Amir Hossein Ghasemi
@RahulGiradkar 我认为WhatsApp解决方案是全屏通知。请查看此帖https://dev59.com/dpfga4cB1Zd3GeqPA8vU#43830658 - user3429953
不对,我发现Skype可以在用户接到电话时直接显示呼叫屏幕,即使屏幕关闭+Skype未运行。 - famfamfam
但是这种方法与您关于Skype的说法兼容。我认为Skype在启动呼叫时应该发送“数据消息”类型的推送通知,以便第二个用户应用程序可以自行管理显示全屏通知。然后从设置在通知的PendingIntent上的Activity中,它应该能够管理检索到的数据以执行P2P呼叫(我的意思是,这只是一个猜测,但我认为应该是可能的)。 - user3429953

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接