这里写了一个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
}
}
网友评论