app名称*表示此app是系统应用,复制到项目后清单文件注册便可启动,此activity无需任何xml文件。
android 11系统以上清单需要配置以下权限:
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
package com.apples.myapplication6;import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextWatcher;
import android.text.style.ForegroundColorSpan;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;public class AppListActivity2 extends Activity {private PackageManager packageManager;private List<ApplicationInfo> appInfoList;private List<ApplicationInfo> filteredAppList;private AppListAdapter adapter;@SuppressWarnings("all")private static View spaceView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);LinearLayout rootLayout = new LinearLayout(this);rootLayout.setLayoutParams(new ViewGroup.LayoutParams(-1, -1));rootLayout.setOrientation(LinearLayout.VERTICAL);LinearLayout headerLayout = new LinearLayout(this);headerLayout.setOrientation(LinearLayout.HORIZONTAL);LinearLayout.LayoutParams params3 = new LinearLayout.LayoutParams(-1, -2);rootLayout.addView(headerLayout, params3);final EditText searchEditText = new EditText(this);searchEditText.setHint("Search apps");searchEditText.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {filterApps(s.toString());}@Overridepublic void afterTextChanged(Editable s) {}});LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, -2, 2);headerLayout.addView(searchEditText, params);spaceView = new View(this);spaceView.setBackgroundColor(Color.parseColor("#F6F6F6"));spaceView.setOnClickListener(v -> {View view2 = AppListActivity2.this.getCurrentFocus();if (view2 != null) {InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);imm.hideSoftInputFromWindow(view2.getWindowToken(), 0);}});LinearLayout.LayoutParams params0 = new LinearLayout.LayoutParams(0, -1, 0.36f);headerLayout.addView(spaceView, params0);Button allBtn = new Button(this);allBtn.setText("App数量");allBtn.setOnClickListener(v -> {Toast.makeText(this, "列表共有:" + filteredAppList.size(), Toast.LENGTH_LONG).show();});LinearLayout.LayoutParams params4 = new LinearLayout.LayoutParams(0, -1, 0.5f);headerLayout.addView(allBtn, params4);Button refreshBtn = new Button(this);refreshBtn.setText("刷新");refreshBtn.setOnClickListener(v -> {spaceView.callOnClick();searchEditText.getText().clear();loadInstalledAppsAsync();});LinearLayout.LayoutParams params5 = new LinearLayout.LayoutParams(0, -1, 0.5f);headerLayout.addView(refreshBtn, params5);RecyclerView recyclerView = new RecyclerView(this);recyclerView.setLayoutManager(new LinearLayoutManager(this));LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(-1, -1);rootLayout.addView(recyclerView, params2);setContentView(rootLayout);packageManager = getPackageManager();appInfoList = new ArrayList<>();filteredAppList = new ArrayList<>();adapter = new AppListAdapter();recyclerView.setAdapter(adapter);loadInstalledAppsAsync();}@SuppressWarnings("all")private void filterApps(String query) {filteredAppList.clear();if (query.isEmpty()) {filteredAppList.addAll(appInfoList);} else {for (ApplicationInfo appInfo : appInfoList) {String appName = packageManager.getApplicationLabel(appInfo).toString().toLowerCase();String packageName = appInfo.packageName;if (appName.contains(query.toLowerCase()) || packageName.contains(query.toLowerCase())) {filteredAppList.add(appInfo);}}}adapter.notifyDataSetChanged();}private void loadInstalledAppsAsync() {new LoadInstalledAppsTask().execute();}@SuppressWarnings("all")private class LoadInstalledAppsTask extends AsyncTask<Void, Void, List<ApplicationInfo>> {private ProgressDialog progressDialog;@Overrideprotected void onPreExecute() {super.onPreExecute();progressDialog = ProgressDialog.show(AppListActivity2.this, null, "加载中……");progressDialog.setCanceledOnTouchOutside(false);progressDialog.setCancelable(false);}@Overrideprotected List<ApplicationInfo> doInBackground(Void... voids) {List<ApplicationInfo> installedApps = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);List<ApplicationInfo> appList = new ArrayList<>();List<ApplicationInfo> systemAppList = new ArrayList<>();List<ApplicationInfo> userAppList = new ArrayList<>();String thatApp = AppListActivity2.this.getPackageName();ApplicationInfo tmpInfo = null;for (ApplicationInfo appInfo : installedApps) {if (thatApp.equals(appInfo.packageName)) {tmpInfo = appInfo;continue;}if (isSystemPackage(appInfo)) {systemAppList.add(appInfo);} else {userAppList.add(appInfo);}}Collections.sort(userAppList, new Comparator<ApplicationInfo>() {@Overridepublic int compare(ApplicationInfo applicationInfo, ApplicationInfo t1) {String aa = packageManager.getApplicationLabel(applicationInfo).toString();String bb = packageManager.getApplicationLabel(t1).toString();return aa.compareTo(bb);}});appList.addAll(userAppList);Collections.sort(systemAppList, new Comparator<ApplicationInfo>() {@Overridepublic int compare(ApplicationInfo applicationInfo, ApplicationInfo t1) {String aa = packageManager.getApplicationLabel(applicationInfo).toString();String bb = packageManager.getApplicationLabel(t1).toString();return aa.compareTo(bb);}});appList.addAll(systemAppList);appList.add(0, tmpInfo);return appList;}@Overrideprotected void onPostExecute(List<ApplicationInfo> appList) {appInfoList.clear();appInfoList.addAll(appList);filteredAppList.clear();filteredAppList.addAll(appList);adapter.notifyDataSetChanged();progressDialog.dismiss();}}private boolean isSystemPackage(ApplicationInfo appInfo) {return (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;}private class AppListAdapter extends RecyclerView.Adapter<AppViewHolder> {@NonNull@Overridepublic AppViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {return new AppViewHolder(parent.getContext());}@Overridepublic void onBindViewHolder(@NonNull AppViewHolder holder, int position) {ApplicationInfo appInfo = filteredAppList.get(position);String appName = packageManager.getApplicationLabel(appInfo).toString();String packageName = appInfo.packageName;boolean isSystemApp = isSystemPackage(appInfo);SpannableStringBuilder appNameBuilder = new SpannableStringBuilder(appName);if (isSystemApp) {int startIndex = appName.length();int endIndex = startIndex + 2;appNameBuilder.append(" *");appNameBuilder.setSpan(new ForegroundColorSpan(Color.RED),startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}holder.bind(appInfo, appNameBuilder, packageName);}@Overridepublic int getItemCount() {return filteredAppList.size();}}@SuppressWarnings("all")private static class AppViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {private ImageView appIconImage;private TextView appNameText;private TextView packageNameText;public AppViewHolder(@NonNull Context context) {super(createItemView(context));appIconImage = itemView.findViewWithTag("appIconImage");appNameText = itemView.findViewWithTag("appNameText");packageNameText = itemView.findViewWithTag("packageNameText");itemView.setOnClickListener(this);}private static View createItemView(Context context) {LinearLayout itemView = new LinearLayout(context);itemView.setLayoutParams(new ViewGroup.LayoutParams(-1, -2));itemView.setOrientation(LinearLayout.HORIZONTAL);itemView.setGravity(Gravity.CENTER_VERTICAL);itemView.setPadding(16, 16, 16, 16);itemView.setBackgroundResource(android.R.drawable.menuitem_background);ImageView appIconImage = new ImageView(context);appIconImage.setTag("appIconImage");appIconImage.setLayoutParams(new LinearLayout.LayoutParams(64, 64));appIconImage.setScaleType(ImageView.ScaleType.CENTER_CROP);itemView.addView(appIconImage);LinearLayout textContainer = new LinearLayout(context);textContainer.setOrientation(LinearLayout.VERTICAL);itemView.addView(textContainer);TextView appNameText = new TextView(context);appNameText.setTag("appNameText");appNameText.setTextSize(18);appNameText.setPadding(16, 0, 0, 0);textContainer.addView(appNameText);TextView packageNameText = new TextView(context);packageNameText.setTag("packageNameText");packageNameText.setPadding(16, 0, 0, 0);textContainer.addView(packageNameText);return itemView;}public void bind(ApplicationInfo appInfo, SpannableStringBuilder appName, String packageName) {appNameText.setText(appName);packageNameText.setText(packageName);new LoadAppIconTask(appIconImage).execute(appInfo);}@Overridepublic void onClick(final View v) {spaceView.callOnClick();PackageManager packageManager = v.getContext().getPackageManager();String packageName = ((TextView) v.findViewWithTag("packageNameText")).getText().toString();if (packageName.equals(v.getContext().getPackageName())) return;try {Intent launcherIntent = new Intent(Intent.ACTION_MAIN);launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER);launcherIntent.setPackage(packageName);final List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(launcherIntent, 0);if (resolveInfos.size() > 1) {String[] acts = new String[resolveInfos.size()];for (int i = 0; i < resolveInfos.size(); i++) {ResolveInfo resolveInfo = resolveInfos.get(i);ActivityInfo activityInfo = resolveInfo.activityInfo;CharSequence label = resolveInfo.loadLabel(packageManager);acts[i] = label + " >>> " + activityInfo.name;}Arrays.sort(acts);new AlertDialog.Builder(v.getContext()).setTitle("LAUNCHER Activity").setCancelable(false).setItems(acts, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterface, int i) {Intent intent = new Intent();ActivityInfo activityInfo = resolveInfos.get(i).activityInfo;intent.setComponent(new ComponentName(activityInfo.packageName, activityInfo.name));v.getContext().startActivity(intent);}}).setNegativeButton("取消", null).create().show();} else {Intent launchIntent = packageManager.getLaunchIntentForPackage(packageName);if (launchIntent != null) {v.getContext().startActivity(launchIntent);} else {Toast.makeText(v.getContext(), "没启动页面", Toast.LENGTH_SHORT).show();}}} catch (Exception e) {e.printStackTrace();}}}@SuppressWarnings("all")private static class LoadAppIconTask extends AsyncTask<ApplicationInfo, Void, Drawable> {private final ImageView appIconImage;public LoadAppIconTask(ImageView appIconImage) {this.appIconImage = appIconImage;}@Overrideprotected Drawable doInBackground(ApplicationInfo... appInfo) {PackageManager packageManager = appIconImage.getContext().getPackageManager();return appInfo[0].loadIcon(packageManager);}@Overrideprotected void onPostExecute(Drawable drawable) {appIconImage.setImageDrawable(drawable);}}
}