java - 使用 addIntentOptions 添加到菜单,为单个 Activity 提供多个 Intent

标签 java android android-intent android-manifest intentfilter

我想尽可能使用 addIntentOptions 来驱动我的菜单。这似乎是提供它们的最干净的方式。无需明确详细说明 Activity ,只需要求一个菜单,列出可用于我的数据项的所有 Activity 。

所以我正在尝试为 ListView 组合一个上下文菜单。它很好用。唯一的问题是我有一个 Activity 有两个使用我的数据类型的 Intent ,但只有第一个出现。

AndroidManifest.xml 中的相关 Activity

<activity android:name=".ui.MyActivity" android:label="The title">
    <intent-filter android:label="First context label">
        <action android:name="com.sample.action.FIRST_ACTION" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.ALTERNATIVE" />
        <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
        <data android:scheme="myscheme" />
    </intent-filter>
    <intent-filter android:label="Second context label">
        <action android:name="com.sample.action.SECOND_ACTION" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.ALTERNATIVE" />
        <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
        <data android:scheme="myscheme" />
    </intent-filter>
</activity> 

生成上下文菜单的代码

@Override
public void onCreateContextMenu(ContextMenu menu, View view, 
        ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, view, menuInfo);

    Uri uri = Uri.fromParts("myscheme", getOpaqueUriOfSelectedItem(view), null)

    Intent intent = new Intent(null, uri);
    intent.addCategory(Intent.CATEGORY_SELECTED_ALTERNATIVE);

    // Search and populate the menu with acceptable offering applications.
    menu.addIntentOptions(
            0, // Menu group to which new items will be added
            0, // Unique item ID (none)
            0, // Order for the items (none)
            this.getComponentName(), // The current Activity name
            null, // Specific items to place first (none)
            intent, // Intent created above that describes our requirements
            0, // Additional flags to control items (none)
            null); // Array of MenuItems that correlate to specific items
                    // (none)
}

正如我所说, Activity 的第一个 Intent 显示在上下文菜单中并且表现得像一个梦。但我没有看到第二个 Intent ,我也没有看到它不应该出现的充分理由。如果 Android 仅允许每个 Activity 具有特定类别的一个 Intent,那将是一个非常蹩脚的限制。

我可以看到自己构建了一个简单地交给 MyActivity 的虚拟 Activity 。但这很笨拙,我想尽可能避免。

编辑:查看从上下文菜单(或选项菜单,大概)传递到 Activity 的 Intent ,即使菜单中显示了两个 Intent , Activity 也不会有足够的信息来判断选择了哪个 Intent ,因为在 Activity 中 getIntent().getAction() 为空。

这似乎是一个不幸的疏忽。可以通过多种方式使用一种类型的数据的 Activity 当然不是那么不寻常?

除非你们中的任何一位好心人知道我遗漏了什么,否则看来我要创建我的虚拟 Activity 。

编辑:正如 CommonsWare 所建议的,我尝试使用 queryIntentActivityOptions。我在上面的代码中的 menu.addIntentOptions 之前添加了这段代码。

PackageManager pm = getPackageManager();
final List<ResolveInfo> available = 
    pm.queryIntentActivityOptions(this.getComponentName(), null, intent, 0);

在调试器中,我发现 available 没有包含 MyActivity 的两个可用 Intent 。所以问题不在 addIntentOptions 内,而是在更深层次的 queryIntentActivityOptions 某处。

最佳答案

我的方法行不通,因为 queryIntentActivityOptions() 和调用它的方法没有按照我的方法所需的方式工作。

对于我的工作方法,您需要为每个匹配的 intent-filter 获得一个结果,这可能会导致每个 Activity 有多个结果。此外,您还需要获取有关哪个 intent-filter 在结果中匹配的信息,特别是 intent-filter 的操作。

但是 queryIntentActivityOptions() 没有找到 intent-filters,它找到了至少有一个匹配的 intent-filter 的 activity。这意味着您每次 Activity 只能获得一个结果。结果也没有提供有关与您的 Intent 相匹配的 Intent 过滤器的信息。

这种方法很有意义,但遗憾的是它不允许一个 Activity 提供多种方式来使用特定的 Intent 。

因此,我的解决方法是为具有多个操作的任何 Activity 创建虚假 Activity ,然后将其移交给真实 Activity 。

所以我在问题中包含的示例 list 将变成

<activity android:name=".ui.MyActivity" android:label="The title" />
<activity android:name=".ui.MyActivityFirstAction" android:label="First action">
    <intent-filter android:label="First context label">
        <action android:name="com.sample.action.FIRST_ACTION" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.ALTERNATIVE" />
        <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
        <data android:scheme="myscheme" />
    </intent-filter>
</activity>
<activity android:name=".ui.MyActivitySecondAction" android:label="Second action">
    <intent-filter android:label="Second context label">
        <action android:name="com.sample.action.SECOND_ACTION" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.ALTERNATIVE" />
        <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
        <data android:scheme="myscheme" />
    </intent-filter>
</activity>

MyActivityFirstAction 和 MyActivitySecondAction 将使用适当的操作和数据简单地调用 MyActivity。

我不太喜欢这个方案,但它仍然保留了在 XML 数据而不是代码中定义的上下文菜单中的所有操作,并允许我使用 addIntentOptions() .

我仍然认为 addIntentOptions() 非常整洁,即使 CommonTasks 告诉我 Google 已经放弃它,我也会继续使用它直到遇到问题。

编辑:正如 CommonsWare 所建议的,也可以创建您自己的库来以非 hackish 方式执行此操作。随着我最终有更多的应用程序,我可能会朝着这个方向前进(除非我找到我更喜欢的现有方法:-))。

关于java - 使用 addIntentOptions 添加到菜单,为单个 Activity 提供多个 Intent ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3886691/

相关文章:

java - 有可能减少这个吗? (或 Java 中的解构赋值)

JAVA HashSet顺序

java - LinkedHashMap 到 LinkedHashMap 或 ArrayList 的逆序

java - 解析字符串并创建 json 格式,然后保存到文本文件

java - 如何填充jsp下拉列表?

android - 单击 ListView 项目时启动应用程序

Android 屏幕方向尺寸

android - 是否可以向用户隐藏特定应用程序?

java - 启动器上出现空指针异常?安卓

java - 使用 url 在 android textview 中定义新方案