【问题标题】:Hand down an Android Intent to another app将 Android Intent 传递给另一个应用程序
【发布时间】:2016-01-14 16:16:52
【问题描述】:

有没有办法让应用接收 Intent 并将其“传递”给下一个应用?

我的意图如下:我想让我的应用程序接收 android.nfc.action.TAG_DISCOVERED 和 android.nfc.action.TECH_DISCOVERED 意图并检查它们的 Extras 以决定如何处理它们:要么触发应用程序中的操作,要么忽略 Intent并将其交给任何其他可能对此感兴趣的应用程序。

据我了解,IntentFilter 仅适用于 Intent 的 Action、Category 或 Data,但不适用于其 Extras。因此,我必须确保我的应用获得所有 Intent,但要与其他应用很好地配合,我需要手动复制此功能。

Android 是否为应用提供了一种方式来告诉它“我不会处理您发送给我的 Intent,将其提供给其他人”?如果没有,我该怎么办?从我的应用重新发送 Intent?

【问题讨论】:

    标签: android android-intent


    【解决方案1】:

    Android 是否为应用提供了一种方式来告诉它“我不会处理您发送给我的 Intent,将其交给其他人”?

    没有。

    Android 不允许您在 Intent 到达其他应用程序之前“拦截”它们。如果是这样,您将陷入棘手的境地,即在它冒泡到其他应用程序之前,尝试决定哪些应用程序应该首先获得 Intent。

    如果没有,我该怎么办?从我的应用重新发送 Intent?

    对于广播意图,您无需执行任何操作。 每个注册了intent-filter来收听广播的应用都会收到广播。

    仅交付给单个应用程序的其他 Intent - 这些是启动活动或服务的 Intent。如果哪个应用程序应该接收这些意图之一有任何歧义(即多个应用程序注册了与意图匹配的意图过滤器),Android 将显示消歧 UI,要求用户选择他们想要使用的应用程序。

    android.nfc.action.TAG_DISCOVERED 和 android.nfc.action.TECH_DISCOVERED 属于后者(根据 their documentation),因此只有一个应用程序能够接收这些事件,并且可能会要求用户选择要使用的应用程序。

    【讨论】:

    • 感谢您的回答。但是,我有以下情况:我有一个标签和三个应用程序,它们的清单中有一个 IntentFilter 为TECH_DISCOVERED。当我在主屏幕并扫描标签时,我会看到三个应用程序的选择器对话框。当我在其中一个应用程序中时,前台的应用程序会识别标签,没有选择器出现,据我所知,其他应用程序永远不会看到 Intent。这里发生了什么事?如果 Intent 是一个广播,不应该所有应用都接收它,而不显示选择器吗?
    • stackoverflow.com/questions/4853622/… 它的答案听起来像是 NFC 意图不是广播——这与我看到的行为一致......
    • 你是对的 - 我已经更新了我的答案以反映这一点。只有一个应用程序能够响应 NFC 事件,用户可以选择哪个应用程序。
    【解决方案2】:

    在对该主题进行了更多研究之后,似乎没有简单的方法可以做到这一点。

    Android 中的Intent 可以寻址到三个不同的收件人类别。这个选择是在发送Intent 时做出的,只有匹配的接收者类的实例才会收到Intent。行为因接收者类和发送Intent 所调用的方法而异。详情请见Intents and Intent Filters。

    • 如果使用startActivity() 或startActivityForResult() 方法,则收件人为Activity。只有一个Activity 会收到意图。如果有多个Activity 与匹配的IntentFilter,则通常会显示一个选择器对话框,以便用户做出选择。选择器对话框依次由另一个Intent 触发,android.intent.action.CHOOSER 作为其操作,充当原始Intent 的包装器。 (see code)

    • 如果使用startService() 或bindService() 方法,Service 将收到Intent。强烈建议(对于 bindService() 甚至从 API 21 开始强制执行)仅在 explicit Intent 上使用这些方法,这些 Intent 唯一地标识了它们的组件。否则 Android 会随机选择匹配的服务,而应用开发者无法控制该选择。

    • 如果使用sendBroadcast()、sendOrdererdBroadcast() 或(现已弃用)sendStickyBroadcast() 方法,BroadcastReceiver 将接收意图。使用sendBroadcast(),Intent 将按随机顺序发送到所有匹配的接收者。使用sendOrderedBroadcast(),收件人将一次收到一个广播。注册BroadcastReceiver后,应用程序可以为其IntentFilter设置优先级,优先级较高的应用程序优先获得Intent。在这种特殊情况下,队列中的任何BroadcastReceiver 都可以在收到Intent 时调用abortBroadcast(),以防止将其传播给优先级较低的收件人。

    现在,正如其他人指出的那样,android.nfc.action.TAG_DISCOVERED 和 android.nfc.action.TECH_DISCOVERED 与 startActivity() 一起发送(或以类似方式)。 Activity 可以使用 NfcAdapter.enableForegroundDispatch() 绕过选择器对话框并将所有 NFC Intent 传递给它们,但这仅在 Activity 位于前台时才有效。

    NFC Intent 的发送方式也很特别:

    • 在发现 NDEF 标签后,Android 将首先尝试发送 android.nfc.action.NDEF_DISCOVERED。

    • 如果没有与IntentFilter匹配的Activity,或者如果标签不是NDEF标签,Android将尝试发送android.nfc.action.TECH_DISCOVERED。

    • 如果仍然没有Activity 与匹配的IntentFilter,Android 将最终尝试发送android.nfc.action.TAG_DISCOVERED。

    Activity Intents 可用于启动服务或通过实现“适配器”Activity 来启动服务或发送广播,该 Activity 接收Intent,触发所需的操作,然后退出。但是,仍有两个主要障碍需要克服:

    • 如果发送 NFC Intent,则只有前台 Activity 能够拦截它。在所有其他情况下,如果有多个潜在收件人,Android 将显示选择器,并且应用无法确定谁获得了Intent——它甚至可能不知道有一个。除非我们正在构建自己的 Android 发行版(我们可以以任何我们想要的方式对其进行篡改),否则我们可能不得不拦截 android.intent.action.CHOOSER 意图并从其额外的 EXTRA_INTENT 中提取原始 Intent - 但由于 @ 987654372@ 也是一个Intent 传递给Activity,我们会遇到同样的问题,即可靠地拦截它并转发我们不感兴趣的内容。
    • 即使对于应用程序收到的 Intent,它也没有简单的方法来“传递”那些它不处理的 Intent。最多,它可以复制 Android 的行为并重新发送它不处理的 Intent。它将使用PackageManager.queryIntentActivities() 或PackageManager.resolveIntentActivities() 来确定其他收件人,并复制上述特定的NFC Intent 逻辑。这只有在 Android 的安全框架没有任何机制来阻止随机应用发送 NFC 意图时才有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      相关资源
      最近更新 更多