Android 系统桌面Launcher 开发

AndroidManifest注册

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

 <activity
     android: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去展示就行了

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值