Как сделать намерение с несколькими действиями

Я хочу отобразить средство выбора активности, которое показывает все приложения, которые могут ПРОСМОТРЕТЬ и / или РЕДАКТИРОВАТЬ некоторые данные. Есть ли простой способ сделать это, или я должен реализовать свой собственный диалог выбора активности? Или, может быть, я могу просто подкласс Intent? Благодарю.

2 ответа

Решение

Я нашел частичное решение с помощью 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);

Я говорю частично, потому что, если приложение поддерживает и ACTION_VIEW, и ACTION_EDIT, оно будет отображаться дважды в списке, одно из которых откроет файл для просмотра, а другое для редактирования, и вы не обязательно будете знать, что есть что. Я думаю, что для полного решения потребовался бы выбор приложения, как предложил Тим.

РЕДАКТИРОВАТЬ (полное решение!):

Я нашел решение, которое не требует написания пользовательских приложений. Чтобы отличить приложения ACTION_EDIT от приложений ACTION_VIEW, я нашел способ добавить строку "(для редактирования)" к меткам для одного из них (в моем случае, 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);

РЕДАКТИРОВАТЬ 2: ошибка

Если по первому намерению действия не найдены, никакие действия не будут отображены, включая действия, обнаруженные вторым намерением. Я закончил тем, что написал свой собственный выбор. Я только что заполнил ExpandableListView заголовками для каждого типа намерений с их соответствующими действиями как дочерними (сохраненными как отдельные LabeledIntents).

Зависит от того, что ваши данные. Но в целом, используя 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"));

Убедитесь, что вы правильно указали свой тип, чтобы приложения знали, что вы хотите открыть что-то, с чем они могут справиться.

РЕДАКТИРОВАТЬ: Я думаю, что вам придется использовать запрос диспетчера пакетов, чтобы получить два списка, затем объединить их в один и создать свой собственный вид деятельности / диалог, который будет всплывать и заполняться данными, содержащимися в вашем объединенном списке.

Вот пример выполнения запроса:

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

так что если вы сделаете свои два намерения и вызовете это дважды, передавая каждое намерение, вы сможете объединить полученные списки, чтобы получить полный набор возможностей. Затем нужно создать действие или диалог, чтобы показать их.

Другие вопросы по тегам