Android 如何使用多个动作来创建一个意图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11021021/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:45:22  来源:igfitidea点击:

How to make an intent with multiple actions

androidandroid-intent

提问by Ken

I want to display an activity chooser that shows all apps that can VIEW and/orEDIT some data. Is there an easy way to do this, or do I have to implement my own activity chooser dialog? Or maybe I can just subclass Intent? Thanks.

我想显示一个活动选择器,显示所有可以查看和/或编辑某些数据的应用程序。有没有一种简单的方法可以做到这一点,或者我是否必须实现自己的活动选择器对话框?或者也许我可以只是子类Intent?谢谢。

回答by Ken

I found a partial solution by using EXTRA_INITIAL_INTENTS:

我通过使用 EXTRA_INITIAL_INTENTS 找到了部分解决方案:

Intent viewIntent = new Intent(Intent.ACTION_VIEW);
Intent editIntent = new Intent(Intent.ACTION_EDIT);
viewIntent.setDataAndType(uri, type);
editIntent.setDataAndType(uri, type);
Intent chooserIntent = Intent.createChooser(editIntent, "Open in...");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { viewIntent });
startActivity(chooserIntent);

I say partial because if an app supports both ACTION_VIEW and ACTION_EDIT it will show up twice in the list, one of which will open the file for viewing and the other for editing, and you wouldn't necessarily know which is which. I think a complete solution would require a custom app chooser, as Tim suggested.

我说部分是因为如果一个应用程序同时支持 ACTION_VIEW 和 ACTION_EDIT,它会在列表中出现两次,其中一个将打开文件进行查看,另一个用于编辑,您不一定知道哪个是哪个。我认为一个完整的解决方案需要一个自定义的应用程序选择器,正如 Tim 建议的那样。

EDIT (Complete Solution!):

编辑(完整的解决方案!):

I found a solution that doesn't involving writing a custom app chooser. In order to differentiate ACTION_EDIT apps from ACTION_VIEW apps, I found a way to append a "(for editing)" string to the labels for one of them (in my case, ACTION_EDIT) by using the line of code Tim provided. In addition, to ensure the appended string doesn't appear to be a part of the app name, I changed the color of it to cyan:

我找到了一个不涉及编写自定义应用程序选择器的解决方案。为了区分 ACTION_EDIT 应用程序和 ACTION_VIEW 应用程序,我找到了一种方法,通过使用 Tim 提供的代码行将“(用于编辑)”字符串附加到其中一个(在我的情况下为 ACTION_EDIT)的标签。此外,为了确保附加的字符串看起来不是应用程序名称的一部分,我将其颜色更改为青色:

PackageManager pm = kyoPrint.getPackageManager();
Intent viewIntent = new Intent(Intent.ACTION_VIEW);
Intent editIntent = new Intent(Intent.ACTION_EDIT);
viewIntent.setDataAndType(uri, type);
editIntent.setDataAndType(uri, type);
Intent openInChooser = Intent.createChooser(viewIntent, "Open in...");

// Append " (for editing)" to applicable apps, otherwise they will show up twice identically
Spannable forEditing = new SpannableString(" (for editing)");
forEditing.setSpan(new ForegroundColorSpan(Color.CYAN), 0, forEditing.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
List<ResolveInfo> resInfo = pm.queryIntentActivities(editIntent, 0);
Intent[] extraIntents = new Intent[resInfo.size()];
for (int i = 0; i < resInfo.size(); i++) {
    // Extract the label, append it, and repackage it in a LabeledIntent
    ResolveInfo ri = resInfo.get(i);
    String packageName = ri.activityInfo.packageName;
    Intent intent = new Intent();
    intent.setComponent(new ComponentName(packageName, ri.activityInfo.name));
    intent.setAction(Intent.ACTION_EDIT);
    intent.setDataAndType(uri, type);
    CharSequence label = TextUtils.concat(ri.loadLabel(pm), forEditing);
    extraIntents[i] = new LabeledIntent(intent, packageName, label, ri.icon);
}

openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
startActivity(openInChooser);

enter image description here

在此处输入图片说明

EDIT 2: BUG

编辑 2:错误

If there are no activities found by the first intent, NO activities will be displayed, including any found by the second intent. I ended up writing my own chooser. I just populated an ExpandableListView with headings for each type of intent with their respective activities as children (stored as individual LabeledIntents).

如果第一个意图没有找到任何活动,则不会显示任何活动,包括第二个意图找到的任何活动。我最终编写了自己的选择器。我只是在 ExpandableListView 中填充了每种类型意图的标题,并将它们各自的活动作为子项(存储为单独的 LabeledIntents)。

回答by FoamyGuy

depends on what your data is. But in general using with ACTION_VIEW and some data attached you can use an IntentChoooser to populate the list of choices to the user.

取决于你的数据是什么。但通常与 ACTION_VIEW 和一些附加数据一起使用,您可以使用 IntentChoooser 向用户填充选择列表。

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "some data");  
startActivity(Intent.createChooser(intent, "Open with"));

Be sure to set your type correctly so that applications will know that you are wanting to open something that they may be able to handle.

确保正确设置您的类型,以便应用程序知道您要打开它们可能能够处理的内容。

EDIT:I think you would have to use a package manager query to get your two lists then combine them into one and make your own activity / dialog that will pop-up and get populated with the data contained in your combined list.

编辑:我认为您必须使用包管理器查询来获取您的两个列表,然后将它们组合成一个并制作您自己的活动/对话框,该活动/对话框将弹出并填充组合列表中包含的数据。

Here is an example making the query:

这是进行查询的示例:

List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(intent, 0);

so if you make your two Intents and call this twice, passing in each intent you should be able to combine the resulting lists to get your full set of possibilities. Then it is up to to create an activity or dialog to show them with.

因此,如果您创建两个 Intent 并调用它两次,传入每个 Intent,您应该能够组合结果列表以获得完整的可能性。然后是创建一个活动或对话框来显示它们。