Подтвердить что ты не робот

Как сделать упор на несколько действий

Я хочу отобразить список действий, который отображает все приложения, которые могут просмотреть и/или ИЗМЕНИТЬ некоторые данные. Есть ли простой способ сделать это, или мне нужно реализовать свой собственный диалог выбора действий? Или, может быть, я могу просто подкласс Intent? Спасибо.

4b9b3361

Ответ 1

Я нашел частичное решение, используя 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, оно будет отображаться дважды в списке, один из которых откроет файл для просмотра, а другой для редактирования, и вы не обязательно будете знать, что именно. Я думаю, что для полного решения потребуется настраиваемый выбор приложений, как предложил Тим.

EDIT (полное решение!):

Я нашел решение, которое не связано с написанием пользовательского выбора. Чтобы отличать приложения ACTION_EDIT от приложений ACTION_VIEW, я нашел способ добавить строку "(для редактирования)" к ярлыкам для одного из них (в моем случае ACTION_EDIT), используя строку кода Tim. Кроме того, чтобы убедиться, что добавленная строка не является частью имени приложения, я изменил ее цвет на голубой:

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

РЕДАКТИРОВАТЬ 2: ОШИБКА

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

Ответ 2

зависит от ваших данных. Но в общем случае с использованием 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"));

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

EDIT: Я думаю, вам нужно будет использовать запрос диспетчера пакетов, чтобы получить ваши два списка, а затем объединить их в один и сделать свое собственное действие/диалог, который будет всплывать и заполняться данные, содержащиеся в вашем объединенном списке.

Вот пример, делающий запрос:

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

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