Android中获取设备已安装的所有浏览器应用列表 并选择指定浏览器展示网页

这篇博客讲述了如何在Android设备上获取已安装的所有浏览器应用列表,并详细介绍了实现过程,包括获取应用列表、判断是否为系统应用,以及如何选择指定浏览器打开网页。在实际操作中,作者遇到了一些未预期的应用(如淘宝、微博)出现在浏览器列表中,经过研究和调整,最终实现了完整获取浏览器列表的目标。

Android中获取设备已安装的所有浏览器应用列表 并选择指定浏览器打开网址

需求:通过下拉选择设备中已安装的浏览器,然后输入网址,打来浏览器展示网页

一.获取浏览器

 private fun getBrowserList(): List<ResolveInfo> {
        val packageManager: PackageManager = getPackageManager()
        val intent = Intent(Intent.ACTION_VIEW)
        intent.data = Uri.parse("http://")
        val activities = packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL)
        return activities
    }

运行结果:发现运行出来还有’淘宝’ '微博’这些APP
运行效果
万能的百度 找到一个博主说淘宝客户端也添加了Intent.CATEGORY_BROWSABLE这个category过滤,通过查看com.android.internal.app.ResolverActivity的代码,于是修改方案如下:

 /**
     * 获取手机内安装的浏览器(过滤淘宝)
     */
    fun getBrowserList(context: Context): List<ResolveInfo> {
        val packageManager = context.packageManager
        val intent = Intent(Intent.ACTION_VIEW)
        intent.addCategory(Intent.CATEGORY_BROWSABLE)
        intent.setData(Uri.parse("http://"))
        val activities =
            packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
        val r0 = activities[0]
        val activity_iter = activities.iterator()
        while (activity_iter.hasNext()) {
            val resolveInfo = activity_iter.next()
            if (r0.priority != resolveInfo.priority || r0.isDefault != resolveInfo.isDefault) {
                activities.remove(resolveInfo)
            }
        }
        return activities
    }

补充: 这里发现只返回了手机默认的浏览器,因为一开始手机只有一个浏览器我以为成功了,结果发现PackageManager.MATCH_DEFAULT_ONLY会因为手机设置了默认浏览器后,无法完整的获取浏览器列表
所以修改成PackageManager.MATCH_ALL 然后发现只是少了’淘宝’上图的’网易云音乐’ ‘微博’ 还是有返回,这个有待研究,有小伙伴知道也望告知

好了到这里浏览器列表就获取到了,接下来就是打开指定浏览器

    /**
     * 启动指定浏览器
     * @param packageName 相应的应用程序packagename
     * @param className 要启动的activity
     */
    private fun toBrowser(packageName: String, className: String, uri: String) {
        val intent = Intent()
        intent.action = "android.intent.action.VIEW"
        val contentUrl: Uri = Uri.parse(uri)
        intent.data = contentUrl
        intent.setClassName(packageName, className)
        startActivity(intent)
        finish()
    }

其实只要修改 intent.setClassName(packageName, className)中相应的应用程序packagename要启动的activity即可启动其他浏览器来
packageName和className都可以在获取浏览器列表中得到

            //获取应用包名
            val packageName = resolveInfo.activityInfo.packageName
            //获取启动activity
            val className = resolveInfo.activityInfo.name
            //获取应用名称
            val name = resolveInfo.loadLabel(packageManager).toString()
            //获取应用图标
            val drawable = resolveInfo.loadIcon(getPackageManager())

这边再做个补充记录好了

获取应用列表
    /**
     * 使用 shell命令行 获取应用列表
     */
    private fun getPkgList(): List<String>? {
        val packages: MutableList<String> = ArrayList()
        try {
            val p = Runtime.getRuntime().exec("pm list packages")
            val isr = InputStreamReader(p.inputStream, "utf-8")
            val br = BufferedReader(isr)
            var line: String = br.readLine()
            while (line != null) {
                line = line.trim { it <= ' ' }
                if (line.length > 8) {
                    val prefix = line.substring(0, 8)
                    if (prefix.equals("package:", ignoreCase = true)) {
                        line = line.substring(8).trim { it <= ' ' }
                        if (!TextUtils.isEmpty(line)) {
                            packages.add(line)
                        }
                    }
                }
                line = br.readLine()
            }
            br.close()
            p.destroy()
        } catch (t: Throwable) {
            t.printStackTrace()
        }
        return packages
    }
     /**
     * 使用packageManager获取设备列表
     */
    private fun getPkgListNew(): List<String>? {
        val packages: MutableList<String> = ArrayList()
        try {
            val packageInfos: List<PackageInfo> = packageManager.getInstalledPackages(
                PackageManager.GET_ACTIVITIES or PackageManager.GET_SERVICES
            )
            for (info in packageInfos) {
                val pkg = info.packageName
                packages.add(pkg)
                if (!isSystemApp(info)) {
                    //获取应用名称
                    val name = info.applicationInfo.loadLabel(packageManager).toString()
                    Log.d("不是系统应用", name)
                }
            }
        } catch (t: Throwable) {
            t.printStackTrace()
        }
        return packages
    }

记得添加权限啊
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />

判断是否是系统应用
    /**
     * 判断是否系统应用
     * 通过packName得到PackageInfo,作为参数传入即可
     */
    private fun isSystemApp(pi: PackageInfo): Boolean {
        val isSysApp = pi.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM == 1
        val isSysUpd = pi.applicationInfo.flags and ApplicationInfo.FLAG_UPDATED_SYSTEM_APP == 1
        return isSysApp || isSysUpd
    }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘟嘟嘟~~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值