Android获取本地所有应用

作者: 奔跑吧李博 | 来源:发表于2022-12-17 20:02 被阅读0次

    这里写了一个demo,获取手机本地所有应用,加载图标和名字,并且可以点击打开该应用,无需任何权限。

    效果如下:
    应用实体类AppInfo:
    data class AppInfo(val pkg: String, val icon: Int, val name: String, val intent: Intent)
    
    NativeAppProvider类用于获取本地应用,根据当前targetsdk版本分为6.0以上和以下分别加载本地应用:
    public class NativeAppProvider {
    
        public static List<AppInfo> checkInstallApps(Context context) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                return checkInstallAppsBeforeL(context);
            } else {
                return checkInstallAppsAfterL(context);
            }
        }
    
        private static List<AppInfo> checkInstallAppsBeforeL(Context context) {
            List<AppInfo> apps = new ArrayList<>();
            PackageManager pm = context.getPackageManager();
            try {
                List<PackageInfo> packageInfos = pm.getInstalledPackages(0);
                for (int i = 0; i < packageInfos.size(); i++) {
                    PackageInfo pkgInfo = packageInfos.get(i);
                    ApplicationInfo appInfo = pkgInfo.applicationInfo;
                    if (TextUtils.equals(context.getPackageName(), pkgInfo.packageName)) continue;
                    Intent intent = getLaunchIntent(pm, pkgInfo.packageName);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    AppInfo app = new AppInfo(pkgInfo.packageName, appInfo.icon, appInfo.loadLabel(pm).toString(), intent);
                    apps.add(app);
                }
            } catch (Exception e) {
                //
            }
            return apps;
        }
    
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        private static List<AppInfo> checkInstallAppsAfterL(Context context) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return null;
            LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
            if (launcherApps == null) return null;
            List<AppInfo> apps = new ArrayList<>();
            try {
                List<LauncherActivityInfo> activityInfos = launcherApps.getActivityList(null, Process.myUserHandle());
                for (LauncherActivityInfo activityInfo : activityInfos) {
                    ApplicationInfo appInfo = activityInfo.getApplicationInfo();
                    Intent intent = new Intent(Intent.ACTION_MAIN);
                    intent.addCategory(Intent.CATEGORY_LAUNCHER);
                    intent.setPackage(appInfo.packageName);
                    intent.setComponent(activityInfo.getComponentName());
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    AppInfo app = new AppInfo(appInfo.packageName, appInfo.icon, activityInfo.getLabel().toString(), intent);
                    apps.add(app);
                }
            } catch (Exception e) {
            }
            return apps;
        }
    
        private static Intent getLaunchIntent(PackageManager pm, String pkg) {
            Intent intent = pm.getLaunchIntentForPackage(pkg);
            if (intent != null) {
                return intent;
            } else {
                intent = new Intent(Intent.ACTION_MAIN);
                intent.addCategory(Intent.CATEGORY_LAUNCHER);
                intent.setPackage(pkg);
                List<ResolveInfo> apps = pm.queryIntentActivities(intent, 0);
                if (apps == null || apps.isEmpty()) {
                    return null;
                }
                ResolveInfo ri = apps.iterator().next();
                if (ri == null) {
                    return null;
                }
                intent.setComponent(new ComponentName(pkg, ri.activityInfo.name));
                return intent;
            }
        }
    }
    
    调用获取本地应用:
    val installedApps = NativeAppProvider.checkInstallApps(applicationContext)
    
    这里是adapter代码,点击item通过intent跳转应用:
    class AppAdapter(val context: Context): RecyclerView.Adapter<AppAdapter.AppViewHolder>() {
        private var datas = ArrayList<AppInfo>()
    
        fun setDatas(datas: ArrayList<AppInfo>) {
            this.datas = datas
            notifyDataSetChanged()
        }
    
        class AppViewHolder(itemView: View): ViewHolder(itemView) {
            var ivIcon: ImageView?= null
            var tvName: TextView?= null
    
            init {
                ivIcon = itemView.findViewById(R.id.iv_icon)
                tvName = itemView.findViewById(R.id.tv_name)
            }
        }
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppViewHolder {
            return AppViewHolder(LayoutInflater.from(context).inflate(R.layout.item, parent, false))
        }
    
        override fun onBindViewHolder(holder: AppViewHolder, position: Int) {
            holder.ivIcon?.background = context.packageManager.getActivityIcon(datas[position].intent)
            holder.tvName?.text = datas[position].name
    
            holder.itemView.setOnClickListener {
                context.startActivity(datas[position].intent)
            }
        }
    
        override fun getItemCount(): Int {
            return datas.size
        }
    }
    

    相关文章

      网友评论

        本文标题:Android获取本地所有应用

        本文链接:https://www.haomeiwen.com/subject/qrnrqdtx.html