安卓使用浏览器打开uri并避免deeplink跳回app

因为项目需要实装了applinks,在代码中使用Intent打开符合applinks规则的链接时,会自动回到app,而不是使用浏览器打开。这是因为在AndroidMainifest.xml文件中声明了data符合该链接的intent-filter,所以使用Intent方式打开该uri时会自动回到app。

那该怎么避免呢?我们可以找到手机上可以打开"https://…"的某应用A。然后intent.setPackage(A)来指定用A应用打开该uri。

直接上代码:


public static void openUrlOnlyInBrowser(String uri, Context context) {
    try {
    	// 随便指定一个https链接
        Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.com"));
        PackageManager packageManager = context.getPackageManager();
        final ResolveInfo resolveInfo;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        	// 请注意:在安卓13及以上需要使用该方法来找到可处理该intent的应用,因为resolveActivity(@NonNull Intent intent, int flags)方法在安卓13sdk中已被标为@Deprecated,需要使用resolveActivity(@NonNull Intent intent, @NonNull ResolveInfoFlags flags)来代替。flag设为MATCH_DEFAULT_ONLY,代表只有支持 Intent.CATEGORY_DEFAULT 的过滤器才会被考虑进行匹配。
            resolveInfo = packageManager.resolveActivity(browserIntent, PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY));
        } else {
        	// 安卓12及以下仍用resolveActivity(@NonNull Intent intent, int flags)来找到可处理该intent的应用。
            resolveInfo = packageManager.resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
        }
        // 请注意: 因为resolveActivity方法的返回值是@Nullable的,所以这里进行一下判空处理
        if (resolveInfo != null) {
            final String defaultPackageName = resolveInfo.activityInfo.packageName;
            final Intent defaultBrowserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
            // 指定处理该intent的应用
            defaultBrowserIntent.setPackage(defaultPackageName);
            try {
            	// 这里就实现了使用默认浏览器来打开该uri了
                context.startActivity(defaultBrowserIntent);
                return;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
		// 一般来说MATCH_DEFAULT_ONLY应该就可以找到默认应用来打开intent了,但万一呢,于是使用MATCH_ALL(慎重使用)来找到可以处理该intent的所有应用们,然后遍历直到成功使用某应用打开该intent。
        final List<ResolveInfo> resolveInfos;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            resolveInfos = packageManager.queryIntentActivities(browserIntent, PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_ALL));
        } else {
            resolveInfos = packageManager.queryIntentActivities(browserIntent, PackageManager.MATCH_ALL);
        }
        for(ResolveInfo info: resolveInfos) {
            final String targetPackageName = info.activityInfo.packageName;
            final Intent targetBrowserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
            targetBrowserIntent.setPackage(targetPackageName);
            try {
                context.startActivity(targetBrowserIntent);
                break;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

最后,也是最最重要的是,在安卓11上新增了软件包可见性,所以我们直接使用上述代码可能访问不到处理该intent的应用。这个时候我们需要在AndroidManifest.xml中声明软件包可见性。

上代码:

	<queries>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="https" />
        </intent>
    </queries>

这样就可以访问到可以处理scheme为https且action为android.intent.action.VIEW的其他应用啦。

如果能帮到为此烦恼的小伙伴们,就很nice了。 也欢迎大家指出该文章中的不足或不对之处~~。
Best Wishes!

参考:
https://blog.csdn.net/qq_41904106/article/details/127107271?spm=1001.2014.3001.5501
https://developer.android.google.cn/guide/topics/manifest/queries-element?hl=en#package

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值