Как исключить мою собственную активность из выбора Activity.startActivity(Intent)?

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

Как следствие, мой основной Activity объявил фильтр намерений для ACTION_SEND_MULTIPLE для image/* mimetypes и может привести к выдаче нового Intent с тем же действием и типом данных, используя Activity.startActivity(Intent).

Есть ли способ исключить мою собственную активность из списка приложений, отображаемых пользователю после вызова startActivity()?


person Kevin Gaudin    schedule 17.10.2010    source источник
comment
Можете ли вы включить в свои намерения что-то еще, что вы можете проверить?   -  person Falmarri    schedule 18.10.2010
comment
Я думал о чем-то подобном, но все, что я могу представить, это тест, чтобы проверить, что моя активность была перезапущена сама по себе. Я бы предпочел, чтобы пользователь не видел этот выбор в списке. Тем не менее, я думаю, что реализую такой обходной путь в качестве быстрого исправления, а затем изучу ответ CommonsWare, чтобы реализовать свой собственный выбор.   -  person Kevin Gaudin    schedule 18.10.2010
comment
Вы можете перенести мое решение для целей URL (stackoverflow.com/a/37988201/1185087), в нем используется псевдоним активности для включать и отключать получение намерений...   -  person user1185087    schedule 23.06.2016


Ответы (2)


Не напрямую, AFAIK. Однако вы можете создать свой собственный выбор, используя PackageManager и queryIntentActivityOptions(), что позволяет отфильтровывать себя (или другие вещи).

person CommonsWare    schedule 17.10.2010
comment
Спасибо, я начал изучать это решение, и я должен достичь того, чего хочу. Однако это была бы хорошая стандартная функция для включения в Android API. - person Kevin Gaudin; 21.10.2010
comment
@Kevin Gaudin: Согласен, хотя это немного второстепенный случай, поэтому я не шокирован тем, что они его не предлагают. - person CommonsWare; 21.10.2010
comment
Может ли кто-нибудь, кто сделал это, предоставить фрагмент, чтобы другие могли увидеть в целом, как это было реализовано? - person lf215; 11.02.2016

Что вам нужно сделать, это:

Запросите доступные приложения для обработки намерения.

  • Если есть действие по умолчанию для его обработки, которое не принадлежит вашему приложению, откройте его напрямую (используя startActivity()).
  • В противном случае отобразите средство выбора намерений, исключая пакет вашего собственного приложения. Таким образом, даже если ваше приложение установлено как приложение по умолчанию для обработки таких намерений, средство выбора все равно будет отображаться, чего вы и хотите.

Вот запись в блоге, объясняющая это более подробно.

Или скопируйте и вставьте код напрямую:


/**
 * Attempts to start an activity to handle the given intent, excluding activities of this app.
 * <ul>
 *     <li>If the user has set a default activity (which does not belong in this app's package), it is opened without prompt.</li>
 *     <li>Otherwise, an intent chooser is displayed that excludes activities of this app's package.</li>
 * </ul>
 *
 * @param context context
 * @param intent intent to open
 * @param chooserTitle the title that will be displayed for the intent chooser in case one needs to be displayed.
 */
static void startActivityExcludingOwnApp(@NonNull Context context, @NonNull Intent intent, @NonNull String chooserTitle) {

    PackageManager packageManager = context.getPackageManager();
    List<Intent> possibleIntents = new ArrayList<>();

    Set<String> possiblePackageNames = new HashSet<>();
    for (ResolveInfo resolveInfo : packageManager.queryIntentActivities(intent, 0)) {

        String packageName = resolveInfo.activityInfo.packageName;
        if (!packageName.equals(context.getPackageName())) {

            Intent possibleIntent = new Intent(intent);
            possibleIntent.setPackage(resolveInfo.activityInfo.packageName);
            possiblePackageNames.add(resolveInfo.activityInfo.packageName);

            possibleIntents.add(possibleIntent);
        }
    }

    @Nullable ResolveInfo defaultResolveInfo = packageManager.resolveActivity(intent, 0);

    if (defaultResolveInfo == null || possiblePackageNames.isEmpty()) {
        throw new ActivityNotFoundException();
    }

    // If there is a default app to handle the intent (which is not this app), use it.
    if (possiblePackageNames.contains(defaultResolveInfo.activityInfo.packageName)) {
        context.startActivity(intent);
    }
    else { // Otherwise, let the user choose.
        Intent intentChooser = Intent.createChooser(possibleIntents.remove(0), chooserTitle);
        intentChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, possibleIntents.toArray(new Parcelable[]{}));
        context.startActivity(intentChooser);
    }
}
person Minas Mina    schedule 09.11.2018