我正在努力使我的应用适应新的Android O方法,尤其是广播接收者的意图。如果我正确理解对服务/广播接收者施加的新限制,我会有些怀疑。我开始尝试一下。我的目标是API级别27(最低API级别26),现在我对结果感到更加困惑。
创建应用 com.example.app
声明(AndroidManifest.xml)广播接收器:
<receiver android:name=".BcastReceiver">
<intent-filter>
<action android:name="com.example.app.WAKE_UP" />
</intent-filter>
</receiver>
让我感到困惑的是通过adb shell进行意图调用的结果:
A)匹配动作
am broadcast -n "com.example.app/.BcastReceiver" -a "com.example.app.WAKE_UP"
B)不匹配的行为
am broadcast -n "com.example.app/.BcastReceiver" -a "nonsense"
C)缺少动作
am broadcast -n "com.example.app/.BcastReceiver"
任何A),B)或C)调用实际上都会导致应用程序实例化,并调用广播接收器。
似乎实际上忽略了动作动作意图过滤器。因此,我在AndroidManifest.xml中删除了意图过滤器:
<receiver android:name=".BcastReceiver"/>
但是使用该声明,A),B)或C)都不能调用广播接收器。似乎必须存在intent过滤器,但其内容将被忽略。有什么提示吗?
答案 0 :(得分:1)
今天我找到了原因。它与android:exported
标志有关。正如official documentation中所述:
默认值取决于广播接收器是否包含 意图过滤器。没有任何过滤器意味着可以 仅由指定其确切类名的Intent对象调用。这个 暗示接收器仅用于内部应用程序 使用(因为其他人通常不会知道类名)。所以在这个 情况下,默认值为“ false”。另一方面,存在 至少一个过滤器意味着广播接收器旨在 接收系统或其他应用程序广播的意图,因此 默认值为“ true”。
如果缺少意图过滤器,则不会导出广播接收器,因此无法从应用程序外部调用广播接收器。如果有一个意图过滤器,则默认情况下将导出广播接收器。 它同时适用于服务和广播接收器-additional limitation不会启动后台应用程序的后台服务。
但是仍然存在与被忽略的操作不一致的情况,但是我个人理解,如果startservice / broadcast是显式的-显式/唯一地命名目标组件-没有理由考虑操作意图过滤器。