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

Android 如何从Activity.startActivity(Intent)选择器中排除我自己的活动?,android,android-activity,android-intent,intentfilter,Android,Android Activity,Android Intent,Intentfilter,我的应用程序可以处理图片。它可以拍摄多张照片作为输入,对其进行处理,然后将其再次发送到另一个应用程序 因此,我的主要活动为图像/*mimetypes在操作_发送_多个上声明了一个意图过滤器,并可能导致使用活动发出具有相同操作和数据类型的新意图 有没有办法将我自己的活动从startActivity()调用后显示给用户的应用程序列表中排除?没有直接排除,好的。但是,您可以使用PackageManager和queryIntentActivityOptions()创建自己的选择器,这样就可以过滤掉您自己

我的应用程序可以处理图片。它可以拍摄多张照片作为输入,对其进行处理,然后将其再次发送到另一个应用程序

因此,我的主要
活动
图像/*
mimetypes在
操作_发送_多个
上声明了一个意图过滤器,并可能导致使用
活动发出具有相同操作和数据类型的新
意图


有没有办法将我自己的活动从
startActivity()
调用后显示给用户的应用程序列表中排除?

没有直接排除,好的。但是,您可以使用
PackageManager
queryIntentActivityOptions()
创建自己的选择器,这样就可以过滤掉您自己(或其他内容)。

您需要做的是:

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

  • 如果有不属于您的应用程序的默认活动来处理它,请直接打开它(使用
    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);
    }
}

/**
*尝试启动活动以处理给定的意图,不包括此应用程序的活动。
*
    *
  • 如果用户设置了默认活动(不属于此应用程序包),则会在不提示的情况下打开该活动
  • *
  • 否则,将显示一个意图选择器,用于排除此应用程序包的活动
  • *
* *@param上下文 *@param意图打开 *@param chooserTitle在需要显示意图选择器时,将为意图选择器显示的标题。 */ 静态void startActivityExcludingOwnApp(@NonNull上下文、@NonNull意图、@NonNull字符串选择器标题){ PackageManager PackageManager=context.getPackageManager(); 列表可能内容=新建ArrayList(); Set possiblePackageNames=new HashSet(); for(ResolveInfo ResolveInfo:packageManager.querytentActivities(intent,0)){ 字符串packageName=resolveInfo.activityInfo.packageName; 如果(!packageName.equals(context.getPackageName())){ 意向可能内容=新意向(意向); 可能的内容setPackage(resolveInfo.activityInfo.packageName); 可能的packagenames.add(resolveInfo.activityInfo.packageName); 可能内容。添加(可能内容); } } @Nullable ResolveInfo defaultResolveInfo=packageManager.resolveActivity(intent,0); if(defaultResolveInfo==null | | possiblePackageNames.isEmpty()){ 抛出新活动NotFoundException(); } //如果有一个默认应用程序来处理该意图(不是此应用程序),请使用它。 if(可能的PackageNames.contains(defaultResolveInfo.activityInfo.packageName)){ 背景。开始触觉(意图); } else{//否则,让用户选择。 Intent-intentChooser=Intent.createChooser(可能的内容.remove(0),chooserTitle); intentChooser.putExtra(Intent.EXTRA_初始意图,可能的内容.toArray(新包裹[]{})); 背景。起始触觉(意向选择); }
}
你能在你的意图中加入一个额外的内容来检查吗?我一直在想类似的事情,但我能想象的只是一个测试来检查我的活动是否已自行重新启动。我希望防止用户在列表中看到此选项。不过,我想我会实现一个快速解决方案,然后探索Commonware的答案来实现我自己的选择器。你可以迁移我的URL意图解决方案(),它使用活动别名来启用和禁用意图接收…谢谢,我开始探索这个解决方案,我应该能够实现我想要的。这将是一个很好的标准功能,可以包含到android api中。@Kevin Gaudin:同意,尽管这有点边缘化,所以我对他们不提供这一功能并不感到震惊。做这项工作的人能否提供一个代码片段,以便其他人可以大致了解它是如何实现的?