Android(安卓)系统桌面Launcher 开发
16lz
2021-01-26
AndroidManifest注册
要想让APP作为Launcher,要添加两个category
查找有桌面图标的APP信息
使用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) }
打开APP的方法
方法一:
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);}
卸载APP的方法
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);}
APP卸载,安装,更新的广播
静态注册(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,所以在获取包名的时候需要做一下处理)
@Overridepublic 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;}
关于APP信息的展示这里就不写了,直接使用RecycleView和GridLayoutManager去展示就行了
更多相关文章
- Android(安卓)Handler机制5--消息发送
- android onNewIntent
- [置顶] android 第三方jar库 反射得到自己的资源ID
- TextView设置autoLink
- Android游戏开发之旅三 View类详解
- Android初级教程_获取Android控件的宽和高 .
- 初涉android中的回调机制
- Android(安卓)如何通过menu id来得到menu item 控件
- Android(安卓)4.4以上 根据uri获取路径的方法