如何从Activity.startActivity(Intent)选择器中排除我自己的Activity?

时间:2010-10-17 23:29:56

标签: android android-activity android-intent intentfilter

我的应用适用于图片。它可以将多张图片作为输入,处理它们,然后再将它们发送到另一个应用程序。

因此,我的主Activity已针对ACTION_SEND_MULTIPLE mimetypes在image/*上声明了一个意图过滤器,并且可能会导致发布具有相同操作和数据的新Intent使用Activity.startActivity(Intent)输入。

有没有办法在startActivity()来电后向用户显示的应用列表中排除我自己的活动?

2 个答案:

答案 0 :(得分:7)

不直接,AFAIK。但是,您可以使用PackageManagerqueryIntentActivityOptions()创建自己的选择器,这样可以自行过滤(或其他内容)。

答案 1 :(得分:0)

您需要做的是:

查询可用的应用程序以处理意图。

  • 如果有默认活动要处理,而不属于您的应用,请直接打开它(使用startActivity())。
  • 否则,显示一个意图选择器,但不包括您自己的应用程序的软件包。因此,即使将您的应用程序设置为处理此类意图的默认应用程序,仍然会显示选择器,这就是您想要的。

Here's a blog post对其进行了更详细的说明。

或直接复制粘贴代码:


/**
 * 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);
    }
}