如何从ACTION_VIEW意图中排除特定应用程序?

12

我正在尝试在浏览器中加载 Twitter 的 URL。

我已经在手机上安装了 Twitter 应用程序,我正在尝试使用 ACTION_VIEW 意图打开 URL。但是当我调用意图时,Android 将显示默认的选择器对话框,其中包含 Twitter 应用程序(如果它已安装在设备上)。我想要只使用浏览器打开 URL,我想从对话框中排除 Twitter 应用程序。我希望所有可用的浏览器都会显示在对话框中,而不是类似于 Twitter、Facebook 等本地应用程序。

是否可能实现这一点?如果可能,有人能帮助我实现吗?我也在此问题中附上了我的代码和屏幕截图以更清楚地说明。

String url = "https://twitter.com";
MimeTypeMap map = MimeTypeMap.getSingleton();
String type = map.getMimeTypeFromExtension(url);
Intent i = new Intent(Intent.ACTION_VIEW);
i.setType(type);
i.setData(Uri.parse(url));
startActivity(i);

在此输入图片描述

3个回答

20

我需要做类似的事情,并且发现这个答案有帮助,我修改了它以使其成为完整的解决方案:

public static void openFileWithInstalledAppExceptCurrentApp(File file, final Activity activity) {
    Intent intent = new Intent();
    intent.setAction(android.content.Intent.ACTION_VIEW);
    MimeTypeMap mime = MimeTypeMap.getSingleton();
    String ext = file.getName().substring(file.getName().indexOf(".")+1);
    String type = mime.getMimeTypeFromExtension(ext);
    intent.setDataAndType(Uri.fromFile(file),type);
    PackageManager packageManager = activity.getPackageManager();
    List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
    String packageNameToHide = "com.test.app";
    ArrayList<Intent> targetIntents = new ArrayList<Intent>();
    for (ResolveInfo currentInfo : activities) {
            String packageName = currentInfo.activityInfo.packageName;
        if (!packageNameToHide.equals(packageName)) {
            Intent targetIntent = new Intent(android.content.Intent.ACTION_VIEW);
            targetIntent.setDataAndType(Uri.fromFile(file),type);
            targetIntent.setPackage(packageName);
            targetIntents.add(targetIntent);
        }
    }
    if(targetIntents.size() > 0) {
        Intent chooserIntent = Intent.createChooser(targetIntents.remove(0), "Open file with");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[] {}));
        activity.startActivity(chooserIntent);
    }
    else {
        Toast.makeText(this, "No app found", Toast.LENGTH_SHORT).show();
    }
}

2
你在 packageNameToHide.equals(packageName) 前面忘记加上 ! 了。现在它总是打开 packageNameOfAppToHide - Roel
@DalvikVM 感谢您的建议。你们都是正确的。我已经修复了这个错误。 :) - Sufian
@lf215很抱歉,在我批准之前,你的编辑已经被拒绝了。我已经做了更正。谢谢。:) - Sufian
2
我的当前应用程序仍然显示在选择器中。我不得不添加这行代码来修复它: targetIntent.setComponent(new ComponentName(packageName, currentInfo.activityInfo.name)); - AndyDeveloper
1
why remove(0)? - user5698345
显示剩余6条评论

4

您只需要将目标包设置为意图即可:

String url = "https://twitter.com";
MimeTypeMap map = MimeTypeMap.getSingleton();
String type = map.getMimeTypeFromExtension(url);
Intent i = new Intent(Intent.ACTION_VIEW);
i.setType(type);
i.setData(Uri.parse(url));
ComponentName comp = new ComponentName("com.android.browser", "com.android.browser.BrowserActivity");
i.setComponent(comp);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

然而,如果用户安装了一些自定义浏览器并想将其设置为默认浏览器,则可能会产生不便。

您可以尝试使用以下代码来检测默认浏览器:

Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("http://example.com"));
List<ResolveInfo> list = context.getPackageManager()
    .queryIntentActivities(i, 0);
// walk through list and select your most favorite browser

没有任何区别,它仍然显示相同的视图。我对你的代码进行了微小的更改,我不知道是否需要。这几乎显示了我设备上的所有应用程序。 - Sanal Varghese
这是修改后的代码。我已经注释了设置数据和类型。String url = "https://twitter.com"; MimeTypeMap map = MimeTypeMap.getSingleton(); String type =map.getMimeTypeFromExtension(url); Intent i = new Intent(Intent.ACTION_VIEW);
//i.setType(type); //i.setData(Uri.parse(url)); //ComponentName comp = new ComponentName("com.android.browser", "com.android.browser.BrowserActivity"); ComponentName comp = new Intent(type, Uri.parse(url)).resolveActivity(this. getPackageManager()); i.setComponent(comp); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(i);
- Sanal Varghese
你正在向系统请求一个应用程序列表,这些应用程序可以处理“http://twitter.com”,其中包括Twitter应用程序。这就是为什么我选择http://google.com进行测试的原因。 - flx
我知道这一点。当你输入google.com时,它不会显示twitter。但是我想要的是,当我使用Twitter网址时,我希望它在浏览器中打开而不是Twitter应用程序中打开。 - Sanal Varghese
再说一遍:这就是为什么我要求处理 ComponentName http://google.com,在你的情况下,这是 IntentChooser。使用我的第一个建议,它将打开浏览器。 - flx
我刚刚更改了第二部分。希望现在更清楚了。 - flx

0

看一下Intent.EXTRA_EXCLUDE_COMPONENTS。这正是你所需要的,但只能在API 24+上使用。

在我的情况下,我有一个要在浏览器中打开的链接。这是一个相应的Intent:

    val intent = Uri
        .parse(url)
        .let { Intent(Intent.ACTION_VIEW, it) }
        .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

然后我搜索了我想要排除的包,比如 "twitter"。

    val excludedApps = packageManager.queryIntentActivities(intent, 0)
        .filter { it.activityInfo.name.contains("twitter") }
        .map {
            ComponentName(it.activityInfo.packageName, it.activityInfo.name)
        }

然后启动带有筛选应用程序的选择器

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        Intent
            .createChooser(intent, null)
            .putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedApps.toTypedArray())
    } else {
        // API 23 and older ignored here
        intent
    }.let {
        startActivity(it)
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接