在实际的项目开发中经常会碰到想把第三方的apk程序直接集成进我们自己的应用中这样的情况。
如果是自己编写的两个应用,那么因为已经知道了这两个应用的包名,所以我们很容易就能控制这两个程序之间的跳转问题。现在的问题是,其中的一个应用我们只有其apk。解决的思路其实一样,可以想办法获取到它的包名,这样就可以用同样的方法进行跳转。
分以下几种情况进行讨论
一、该应用已经安装
这里介绍两种方法:
1、枚举所有安装的应用
根据设置的条件进行筛选,使用PackageManager的public abstract List getInstalledPackages (int flags) 方法可以获得安装应用的列表。
用这个方法po主实现了一个类似文件管理器的应用,可以获取测试机上所有已装的程序并启动,获取的分别为应用程序名称,应用程序包名,应用程序入口Activity名称。
sample下载地址:http://download.youkuaiyun.com/detail/u012505618/9361143,
当获取了应用程序包名,应用程序入口Activity名称就可以进行跳转:
// 启动代码:
PackageManager pm;
// 初始化pm, 比如在activity里可以PackageManager pm = getPackageManager();
// PackageInfo 包含丰富的包的信息,这个'包的名称'是什么,在AndroidManifest.xml中有明确定义
PackageInfo pi = pm.getPackageInfo("包的名称", PackageManager.GET_ACTIVITIES);
ActivityInfo ai=pi.activities[0]; // ActivityInfo同样道理是Activity的信息
//这里指向第一个包中的Activity, 大多数都是第一个Activity为启动Activity
if(ai==null) throw new Exception(pkg+"不包含任何Activity");
String sName=ai.name;
String pkg = ai.packageName;
// pck: 应用的包名
// sName: 应用程序入口Activity名称
ComponentName componet = new ComponentName(pkg, sName);
Intent intent = new Intent();
intent.setComponent(componet);
startActivity(intent);
趁这个机会总结了一下Info系列的类
PackageItemInfo:包含了一些信息的基类,它的直接子类有:ApplicationInfo、ComponentInfo、InstrumentationInfo、PermissionGroupInfo、PermissionInfo。它的间接子类有:ActivityInfo、ProviderInfo、ServiceInfo。这个类包含的信息对于所有包中项目是平等的。这些Package items是被Package manager所持有的。这个类提供了属性的非常普通的基本设置:label、icon和meta-data。这个类的意图不是被自己调用。它在这只是简单地分享被package manager返回的所有items之间的普通定义。比如,它自己并不实现Parcelable接口,但却帮助实现了Parcelable的子类提供了方便的方法。
ApplicationInfo是从一个特定的应用得到的信息。这些信息是从相对应的Androdimanifest.xml的标签中收集到的。
ResolveInfo这个类是通过解析一个与IntentFilter相对应的intent得到的信息。它部分地对应于从AndroidManifest.xml的标签收集到的信息。
PackageManager这个类是用来返回各种的关联了当前已装入设备了的应用的包的信息。你可以通过getPacageManager来得到这个类。
ApplicationInfo与ResolveInfo比较:前者能够得到Icon、Label、meta-data、description。后者只能得到Icon、Label。
下面讲一下这几个类综合在一起的具体应用:
通过调用PackageManager的方法可以得到两种不同的信息:
首先要得到manager:
PackageManager manager = getPackageManager();
method 1:
List appList = manager.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
它是通过解析AndroidManifest.xml的标签中得到的,所以它能得到所有的app。
method 2:
Intent intent = new Intent(Intent.A CTION_MAIN,null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List appList = manager.queryIntentActivities(intent,0);
它是通过解析标签得到有
2、利用广播的方式
MyBroadcastReceiver myReceiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_INSTALL);
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addDataScheme("package");
registerReceiver(myReceiver, filter);
监视安装,在MyBroadcastReceiver的onReceive函数里
public void onReceive(Context arg0, Intent intent) {
String sPackageName=intent.getDataString(); //这个就是包名
}
也可以使用 AndroidManifest.xml配置来监视。
二、该程序没有被安装
这个能否实现po主并没有进行验证,各位如果有这个需求可以参考下面这篇文章: