千家信息网

怎么使用Intent打开第三方应用及验证可用性

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章给大家分享的是有关怎么使用Intent打开第三方应用及验证可用性的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。基础知识1. App 的入口 Activity 与其
千家信息网最后更新 2026年11月01日怎么使用Intent打开第三方应用及验证可用性

这篇文章给大家分享的是有关怎么使用Intent打开第三方应用及验证可用性的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

基础知识

1. App 的入口 Activity 与其 icon

一个普通的应用默认会有一个入口 Activity,它在 AndroidManifest.xml 中一般这样写:

                                                                         ...   

只有配置了一个这样的 Activity,这个应用才会点击的时候知道启动哪个 Activity,如果把 category 的值修改为 android.intent.category.DEFAULT 那么,这个应用将在桌面看不到 icon,无法直接打开了。

使用 Intent 打开第三方应用或指定 Activity 的方式

只知道包名 - 需要有默认的入口 Activity

启动指定第三方应用的 Activity - 需要包名和 Activity 名,且该 Activity 的 Export="true"

隐式启动第三方应用

1. 使用 PackageManager.getLaunchIntentForPackage()

String package_name="xx.xx.xx";   PackageManager packageManager = context.getPackageManager();   Intent it = packageManager.getLaunchIntentForPackage(package_name);   startActivity(it);

该方法针对只知道包名,想要启动该应用时使用,对该应用的***限制是 有默认的入口 Activity 。

当没有默认的入口 Activity 时,会报 NullPointerException 异常:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Intent.toString()' on a null object reference

再看看 getLaunchIntentForPackage() 方法的说明:

/**        * Returns a "good" intent to launch a front-door activity in a package.        * This is used, for example, to implement an "open" button when browsing        * through packages.  The current implementation looks first for a main        * activity in the category {@link Intent#CATEGORY_INFO}, and next for a        * main activity in the category {@link Intent#CATEGORY_LAUNCHER}. Returns       * null if neither are found.       *        * @param packageName The name of the package to inspect.      *        * @return A fully-qualified {@link Intent} that can be used to launch the        * main activity in the package. Returns null if the package        * does not contain such an activity, or if packageName is not        * recognized.        */       public abstract Intent getLaunchIntentForPackage(String packageName);

所以使用此方式判定 Intent 是否为空即可。

String package_name = "xx.xx.xx";   PackageManager packageManager = getPackageManager();   Intent it = packageManager.getLaunchIntentForPackage(package_name);   if (it != null){       startActivity(it);   }else{       //没有默认的入口 Activity   }

2. 使用 Intent.setComponent()

String package_name = "xx.xx.xx";   String activity_path = "xx.xx.xx.ab.xxActivity";   Intent intent = new Intent();   intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//可选   ComponentName comp = new ComponentName(package_name,activity_path); intent.setComponent(comp);   startActivity(intent);

此方式可以启动一个应用指定的 Activity,不限于默认入口 Activity。但此方式要求的条件多,如下:

知道 App 的包名和 Activity 的全路径及其名称

需要启动的目标 Activity 在 AndroidManifest.xml 中的属性 Export="true"

那这种方式下,如何判断目标 Activity 是否存在呢?

下面是网上流传的非常普遍的用法:

String package_name = "xx.xx.xx";   String activity_path = "xx.xx.xx.ab.xxActivity";   Intent intent = new Intent();   intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//可选   ComponentName cn = new ComponentName(package_name,activity_path);   intent.setComponent(cn);     if (intent.resolveActivity(getPackageManager()) != null) {       startActivity(intent);   } else {       //找不到指定的 Activity   }

遗憾的是, Intent.resolveActivity() 方法并不能判定此方式所要启动的 Activity 是否存在,如果此 Activity 不存在,会报 java.lang.IllegalArgumentException: Unknown component 异常,并导致程序崩溃。

下面看下 resolveActivity() 的代码,以及它的 相似方法 resolveActivityInfo() :

public ComponentName resolveActivity(PackageManager pm) {      if (mComponent != null) {          return mComponent;      }      ResolveInfo info = pm.resolveActivity(this,          PackageManager.MATCH_DEFAULT_ONLY);      if (info != null) {          return new ComponentName(              info.activityInfo.applicationInfo.packageName,              info.activityInfo.name);      }      return null;  }     public ActivityInfo resolveActivityInfo(PackageManager pm, int flags) {       ActivityInfo ai = null;       if (mComponent != null) {           try {               ai = pm.getActivityInfo(mComponent, flags);           } catch (PackageManager.NameNotFoundException e) {               // ignore           }       } else {           ResolveInfo info = pm.resolveActivity(this,               PackageManager.MATCH_DEFAULT_ONLY | flags);           if (info != null) {               ai = info.activityInfo;           }       }         return ai;   }

显而易见,我们此方式就是先设置的 ComponentName,所以会直接 return mComponent 给我们,并没有任何判定的逻辑。相对的, resolveActivityInfo() 则可以进行有效判定并返回 null。故,我们选择使用 Intent.resolveActivityInfo() 进行此方式下的判定:

String package_name = "xx.xx.xx";   String activity_path = "xx.xx.xx.ab.xxActivity";   Intent intent = new Intent();   intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//可选   ComponentName cn = new ComponentName(package_name,activity_path);   intent.setComponent(cn);     if (intent.resolveActivityInfo(getPackageManager(), PackageManager.MATCH_DEFAULT_ONLY) != null) {       startActivity(intent);   } else {       //找不到指定的 Activity   }

3.隐式启动第三方应用

此方式多用于启动系统中的功能性应用,比如打电话、发邮件、预览图片、使用默认浏览器打开一个网页等。

> Intent intent = new Intent();   > intent.setAction(action);   > intent.addCategory(category);   > intent.setDataAndType("abc://www.dfg.com","image/gif");   > startActivity(intent);   >

条件1:IntentFilter 至少有一个 action 至少有一个Category,可以没有 Data 和 Type

条件2:如果有 Data,参数中 Data 必须符合 Data 规则

条件3:Action 和 Category 必须同时匹配 Activity 中的一个 Action 和一个 Category (Category 默认:android.intent.category.DEFAULT)

隐式启动功能繁多,就不一一列举了,需要时直接搜索相关代码即可,我们用打开一个网页为例:

Uri uri = Uri.parse("http://www.abc.xyz");   Intent intent = new Intent(Intent.ACTION_VIEW, uri);   startActivity(intent);

这时,直接使用 Intent.resolveActivity() 方法没什么问题:

Uri uri = Uri.parse("http://www.abc.xyz");   Intent intent = new Intent(Intent.ACTION_VIEW, uri);    if (intent.resolveActivity(getPackageManager()) != null) {       startActivity(intent);   } else {       // 没有安装所需应用   }

总结

经过阅读 PackageManager 的代码,发现还可以使用 packageManager.queryIntentActivities() 方法判断系统里是否有能解析指定 Intent 的应用。

public boolean isAvailable(Context context, Intent intent) {       PackageManager packageManager = context.getPackageManager();       List list = packageManager.queryIntentActivities(intent,       PackageManager.MATCH_DEFAULT_ONLY);       return list.size() > 0;   }

那么,总结下来就是:

方式一 PackageManager.getLaunchIntentForPackage() ,直接判断返回的 Intent 是否为空即可;

方式二 Intent.setComponent() ,使用 Intent.resolveActivityInfo() 或者 packageManager.queryIntentActivities() 两种方式;

方式三 隐式启动,使用 Intent.resolveActivity() 、 Intent.resolveActivityInfo() 、 packageManager.queryIntentActivities() 三种方式均可。

感谢各位的阅读!关于"怎么使用Intent打开第三方应用及验证可用性"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

应用 方式 入口 第三方 方法 条件 代码 可用性 验证 内容 功能 少有 就是 更多 目标 知识 篇文章 系统 网页 会报 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州紫鲸互联网科技有限公司 互联网科技公司税收优惠 疫情对互联网科技公司影响 智网互联网科技 狮子座互联网科技培训 深圳艾佳互联网科技 新华互联网科技校企合作 湖南洣水互联网科技有限公司扣款 茂名市互联网科技产业园 互联网对科技的发展 中国航天科技大学国际工业互联网 中和天地互联网科技有限公司 小米互联网科技园入驻 杭州披云加互联网科技有限公司 半导体行业属于互联网高科技类吗 上海乐五互联网科技有限公司 互联网公司属于科技吗 互联网科技收购价值 北京互联网科技类企业分布 互联网科技创新方面的资料 互联网新科技 互联网科技工作委员会副主任毛军 科技金融是不是互联网金融 科技股互联网 万易互联网科技 济南华为互联网科技产业总部基地 互联网科技中介 链环科技传统企业怎么转型互联网 沐思想互联网科技有限公司 上海钢联属于互联网科技股吗
0