Question

My app works with pictures. It can take multiple pictures as an input, process them, and send them again to another app.

As a consequence, my main Activity has declared an intent filter on ACTION_SEND_MULTIPLE for image/* mimetypes and can result in issuing a new Intent with the same action and data type using Activity.startActivity(Intent).

Is there a way to exclude my own activity from the list of apps that is displayed to the user after the startActivity() call ?

Was it helpful?

Solution

Not directly, AFAIK. However, you could create your own chooser using PackageManager and queryIntentActivityOptions(), which does allow for filtering yourself (or other things) out.

OTHER TIPS

What you need to do is:

Query the available apps to handle the intent.

  • If there is a default activity to handle it, which does not belong to your app, open it directly (using startActivity()).
  • Otherwise, display an intent chooser excluding the package of your own app. So even if your app is set as the default app to handle such intents, the chooser will still be shown, which is what you want.

Here's a blog post explaining it in a bit greater detail.

Or copy-paste the code directly:


/**
 * 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);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top