当前位置: 代码迷 >> 综合 >> Android 系统桌面Launcher 开发
  详细解决方案

Android 系统桌面Launcher 开发

热度:35   发布时间:2023-10-28 05:32:53.0

AndroidManifest注册

要想让APP作为Launcher,要添加两个category

 <activityandroid:name=".MainActivity"android:launchMode="singleTask"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.HOME" /><category android:name="android.intent.category.DEFAULT" /></intent-filter>
</activity>

查找有桌面图标的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<ResolveInfo> 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以后系统对广播的注册更加严格了,静态注册的广播可能会收不到,推荐使用动态注册)

<receiver android:name=".broadcast.AppChangeBroadcast"><intent-filter><action android:name="android.intent.action.PACKAGE_ADDED" /><action android:name="android.intent.action.PACKAGE_REMOVED" /><action android:name="android.intent.action.PACKAGE_REPLACED" /><data android:scheme="package" /></intent-filter>
</receiver>

动态注册(注意要反注册哦,不然可能会出现异常)

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;
}

关于APP信息的展示这里就不写了,直接使用RecycleView和GridLayoutManager去展示就行了

  相关解决方案