在Android Oreo中,清单文件中注册的广播接收器没有被调用。

12

我已注册以下接收器,在Android Oreo上未被调用,但在较低版本设备上可以正常工作。

<receiver
     android:name=".common.receiver.ConsultReceiver"
     android:exported="false">
       <intent-filter>
            <action android:name="APP_STARTED" />
            <action android:name="APP_STARTED_FROM_ORGANIC" />
       </intent-filter>
</receiver>  

有什么可以帮忙的吗?

4个回答

11
一般情况下,在 Android 8.0+ 上不能使用隐式 Intent(例如仅具有操作字符串的 Intent)进行广播。 您的 <receiver> 未导出。这表明以下三种情况之一:
  1. 您正在将其与 PendingIntent 结合使用,例如用于 Notification。如果是这样,请摆脱 <intent-filter> 并在创建指向此接收器的 PendingIntent 时使用显式 Intent (new Intent(this, ConsultReceiver.class))。

  2. 您正在将其作为应用程序中多个进程之间的某些 IPC 的一部分使用。在这种情况下,也请使用显式 Intent

  3. 您仅在应用程序内的一个进程中纯粹使用此接收器。在这种情况下,请摆脱 <receiver> 并使用其他内容(LocalBroadcastManager、事件总线、RxJava、LiveData 等)。


1
@Ragini:一个接收器既不是隐式的也不是显式的。一个Intent可以是隐式的或显式的。显式的Intent标识组件的Java类;而隐式的Intent则不是这样。 - CommonsWare
@SantanuSur:你需要一个<receiver>元素。它不需要一个<intent-filter> - CommonsWare
1
@SantanuSur:如果您的问题是关于FCM是否会改变Intents的显式使用方式,我不清楚。在Android 8.x中启动活动方面没有任何变化。 - CommonsWare
1
@SantanuSur:正确。请注意,从推送消息启动活动可能会打断用户正在进行的操作,这可能会让用户感到不满意。考虑改为发送通知。 - CommonsWare
1
@Jenix:“对于隐式意图,像Intent.ACTION_CALL这样的东西也是一样的吗?”--那不用于广播。 “在AndroidManifest.xml中进行静态注册仍然有效,例如<action android:name="android.intent.action.BOOT_COMPLETED"/>吗?”--只有当操作在白名单上时才有效。 android.intent.action.BOOT_COMPLETED恰好在白名单上,但大多数操作都不在白名单上。 - CommonsWare
显示剩余7条评论

6

如果你的应用程序目标API级别为26或更高,则不能使用清单声明接收器来接收隐式广播(不特定于你的应用程序的广播),除了一些被豁免的隐式广播。在大多数情况下,你可以使用计划任务来代替。


但它不是隐式广播接收器。 - Ragini

3
在Android 8.0及以上版本中,使用以下代码检查某个应用程序是否已安装或卸载。
class MainActivity : AppCompatActivity() {

    private val receiver = YourBroadcastReceiverClass()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val filter = IntentFilter();
        filter.addAction(Intent.ACTION_PACKAGE_ADDED)
        filter.addAction(Intent.ACTION_PACKAGE_REMOVED)
        filter.addDataScheme("package")

        registerReceiver(receiver, filter)
    }

    override fun onDestory() {
        unregisterReceiver(receiver)
        super.onDestroy()
    }
}

2

使用setPackageIntent限制在您的包内,以保障安全性。


这个是足够的吗? - virsir

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