显示android设备所以已安装App 可点击启动、搜索
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;
@Override
protected 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() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
filterApps(s.toString());
}
@Override
public 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;
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(AppListActivity2.this, null, "加载中……");
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
}
@Override
protected 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>() {
@Override
public 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>() {
@Override
public 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;
}
@Override
protected 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
@Override
public AppViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new AppViewHolder(parent.getContext());
}
@Override
public 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);
}
@Override
public 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);
}
@Override
public 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() {
@Override
public 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;
}
@Override
protected Drawable doInBackground(ApplicationInfo... appInfo) {
PackageManager packageManager = appIconImage.getContext().getPackageManager();
return appInfo[0].loadIcon(packageManager);
}
@Override
protected void onPostExecute(Drawable drawable) {
appIconImage.setImageDrawable(drawable);
}
}
}