要想让APP作为Launcher,要添加两个category
使用PackageManager的queryIntentActivities(intent,flags)方法获取APP
再intent中设置查找的条件
Intent的action为Intent.ACTION_MAIN
intent的category为Intent.CATEGORY_LAUNCHER
flags: MATCH_DEFAULT_ONLY :Category必须带有CATEGORY_DEFAULT的Activity,才匹配
GET_INTENT_FILTERS :匹配Intent条件即可
GET_RESOLVED_FILTER :匹配Intent条件即可
PackageManager pm = BaseApp.getContext().getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List resolveInfos = pm.queryIntentActivities(intent, 0);
for (ResolveInfo resolveInfo : resolveInfos) {
Log.d(TAG, "static initializer: " + resolveInfo.activityInfo.packageName);
AppInfo app = new AppInfo();
app.setName(resolveInfo.loadLabel(pm).toString());
app.setIcon(resolveInfo.loadIcon(pm));
app.setIconBase64(PhotoUtil.drawableToBase64(resolveInfo.loadIcon(pm)));
app.setPackageName(resolveInfo.activityInfo.packageName)
}
方法一:
public static void openApp(Context context, String packageName) {
try {
PackageManager pm = context.getPackageManager();
Intent intent = pm.getLaunchIntentForPackage(packageName);
context.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
ToastUtil.showToast(App.getContext(), "打开失败!");
}
}
方法二:app有多个入口时,使用该方法
public void openApp(Context context, ResolveInfo resolveInfo){
Intent intent=new Intent();
intent.setComponent(new ComponentName(resolveInfo.activityInfo.packageName,resolveInfo.activityInfo.name));
context.startActivity(intent);
}
public static void unstallApp(Context context, String packageName) {
Intent uninstall_intent = new Intent();
uninstall_intent.setAction(Intent.ACTION_DELETE);
uninstall_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
uninstall_intent.setData(Uri.parse("package:" + packageName));
context.startActivity(uninstall_intent);
}
静态注册(android8以后系统对广播的注册更加严格了,静态注册的广播可能会收不到,推荐使用动态注册)
动态注册(注意要反注册哦,不然可能会出现异常)
mAppChangeBroadcast = new AppChangeBroadcast();
IntentFilter filter=new IntentFilter();
filter.addAction("android.intent.action.PACKAGE_ADDED");
filter.addAction("android.intent.action.PACKAGE_REMOVED");
filter.addAction("android.intent.action.PACKAGE_REPLACED");
filter.addDataScheme("package");
registerReceiver(mAppChangeBroadcast,filter);
广播接收者(注意这里有坑,通过intent.getDataString()拿到的值不是包名,而是package:com.android.xxx,所以在获取包名的时候需要做一下处理)
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive: action=" + intent.getAction());
if("android.intent.action.PACKAGE_ADDED".equeal(intent.getAction())){
String package=intent.getDataString().substring(8);
}
}
广播接收者能收到的只有安装的应用的包名,但是我们需要整个应用的信息,大部分人可能会采用一下的方法来获取apk的信息
PackageManager pm = BaseApp.getContext().getPackageManager();
PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
这种方式存在一点点问题,因为我们安装的应用有可能是没有入口的,我们并不需要展示。使用这种方式我们无法区分应用有没有入口,我们可以使用以下方式,同我们获取所有有入口的apk的方式类似,只需要把我们的包名添加上就可以了。如下:
PackageManager pm = BaseApp.getContext().getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setPackage(packageName);
ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
if (null==resolveInfo){
Log.d(TAG, "addAppInfo: 安装的APK没有入口");
return;
}