先讲讲需求:
1.我们提供一个我方APP支持的应用市场列表a
2.然后在本机上获取所有满足uri(即可根据包名跳到相应应用详情的接口)的列表b
3.取交集后显示在应用选择器上
4.返回是否成功打开chooser
代码如下:
由于从c++传字符串数组比较麻烦,所以约定将列表a(marketName)的包名用“#”分隔
public static boolean openAppMarket(String marketName, String packageName) {
//定义打开市场时使用的intent
Intent marketIntent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse("market://details?id=" + packageName);
marketIntent.setData(uri);
//获取本机所有市场类应用名
List<ResolveInfo> infos = pm.queryIntentActivities(marketIntent, 0);
//如果本地没有应用市场
if (infos == null || infos.size() == 0 ) {
return false;
}
//指定的几个市场的包名
String[] markets = marketName.split("#");
ArrayList<Intent> targetIntents = new ArrayList<Intent>();
//取交集
for (ResolveInfo ri: infos) {
ActivityInfo activityInfo = ri.activityInfo;
String pName = activityInfo.packageName;
for (int j = 0; j < markets.length; j++) {
if (pName.equals(markets[j])) {
Intent intent1 = new Intent(marketIntent);
intent1.setPackage(pName);
intent1.setClassName(pName, activityInfo.name);
targetIntents.add(intent1);
break;
}
}
}
if (targetIntents.size() == 0 ) {
return false;
}
//打开应用选择器,第二个参数是chooser显示的提示文字
Intent chooser = Intent.createChooser(targetIntents.remove(0), getString(STRING_CHOOSE_MARKET));
if (targetIntents.size() > 0) {
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[] {}));
}
try {
sActivity.get().startActivity(chooser);
return true;
} catch (android.content.ActivityNotFoundException ex) {
return false;
}
}
对上方3处红色代码的解释:
1.通过指定intent的包名和类名来确定应用,然后添加到列表b
2.createchooser时使用targetIntents.remove(0)即传入targetIntents的第一个intent,并将其移除,
否则执行chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[] {}));添加后启动时会出现两个相同的应用
(但经过测试,小米手机竟然会自动移除重复的应用)
3.将需要补充的应用intent列表传入chooser
//下面这两个方法是用来获取字符串的,不重要
public static int getStringID(final String id) {
return sActivity.get().getResources()
.getIdentifier(id, "string", sActivity.get().getPackageName());
}
public static String getString(final String id) {
return sActivity.get().getResources().getString(getStringID(id));
}