apk 包可以使用PackageManager获取,apk 包中的资源可以获取其对应的Context,再通过Context获取对应的Resouce获取提示2: apk 是指已经安装过的程序,不是存在sdcard. 上的apk安装包.
先上效果图
开始代码部分
首先是布局文件activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.nf.applist.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="48dp" android:paddingLeft="16dp" android:paddingRight="16dp"> <Switch android:id="@+id/switch_type" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="true" /> <EditText android:id="@+id/edit_input" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:hint="请输入包名前缀" android:singleLine="true" android:textColor="#333333" android:textSize="14sp" /> <Button android:id="@+id/btn_scan" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="扫描" android:textColor="#333333" android:textSize="14sp" /> </LinearLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/list_view" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:id="@+id/tv_empty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="没有找到任何包" android:textColor="#333333" android:textSize="14sp" android:visibility="gone" /> </RelativeLayout> </LinearLayout>
ListView的item布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="58dp" android:gravity="center_vertical" android:paddingLeft="16dp" android:paddingRight="16dp"> <!-- tools 域 表示 仅在预览时生效 --> <ImageView android:id="@+id/iv_app_icon" android:layout_width="40dp" android:layout_height="40dp" tools:src="@mipmap/ic_launcher" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="16dp" android:orientation="vertical"> <TextView android:id="@+id/tv_app_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#333333" android:textSize="14sp" tools:text="应用名称" /> <TextView android:id="@+id/tv_app_package" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="2dp" android:textColor="#888888" android:textSize="12sp" tools:text="应用包名" /> </LinearLayout> </LinearLayout>
然后是实体类SimpleAppInfo.class
public class SimpleAppInfo { private String appName; private String appPackage; private Drawable appIcon; private String valuesAppName; private Drawable drawablePreiewImg; private boolean system; private String packagePath; private String versionName; private int versionCode; public SimpleAppInfo(String appName, String appPackage, Drawable appIcon, boolean system, String packagePath, String versionName, int versionCode) { this.appName = appName; this.appPackage = appPackage; this.appIcon = appIcon; this.system = system; this.packagePath = packagePath; this.versionName = versionName; this.versionCode = versionCode; } public String getPackagePath() { return packagePath; } public void setPackagePath(String packagePath) { this.packagePath = packagePath; } public String getVersionName() { return versionName; } public void setVersionName(String versionName) { this.versionName = versionName; } public int getVersionCode() { return versionCode; } public void setVersionCode(int versionCode) { this.versionCode = versionCode; } public boolean isSystem() { return system; } public void setSystem(boolean system) { this.system = system; } public String getAppName() { return appName; } public void setAppName(String appName) { this.appName = appName; } public String getAppPackage() { return appPackage; } public void setAppPackage(String appPackage) { this.appPackage = appPackage; } public Drawable getAppIcon() { return appIcon; } public void setAppIcon(Drawable appIcon) { this.appIcon = appIcon; } public String getValuesAppName() { return valuesAppName; } public void setValuesAppName(String valuesAppName) { this.valuesAppName = valuesAppName; } public Drawable getDrawablePreiewImg() { return drawablePreiewImg; } public void setDrawablePreiewImg(Drawable drawablePreiewImg) { this.drawablePreiewImg = drawablePreiewImg; } }
接下来就是核心代码了MainActivity.class
public class MainActivity extends AppCompatActivity { private TextView tvEmpty; private ListView listView; private Button btnScan; private EditText editInput; private List<SimpleAppInfo> filterAppList = new ArrayList<>(); private BaseAdapter appListAdapter; private Switch switchType; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvEmpty = findViewById(R.id.tv_empty); listView = findViewById(R.id.list_view); btnScan = findViewById(R.id.btn_scan); editInput = findViewById(R.id.edit_input); switchType = findViewById(R.id.switch_type); switchType.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { appListAdapter.notifyDataSetChanged(); } }); btnScan.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //防止重复点击 btnScan.setEnabled(false); listView.setVisibility(View.GONE); tvEmpty.setVisibility(View.VISIBLE); tvEmpty.setText("正在扫描"); //开子线程做耗时的工作 new Thread() { @Override public void run() { final List<SimpleAppInfo> appsInfo = getAppsInfo(); //切换到主线程 更新数据 runOnUiThread(new Runnable() { @Override public void run() { String filterStr = editInput.getText().toString().trim(); if (TextUtils.isEmpty(filterStr)) { filterAppList = appsInfo; } else {//过滤 filterAppList.clear(); for (SimpleAppInfo appInfo : appsInfo) { if (appInfo.getAppPackage().startsWith(filterStr)) { filterAppList.add(appInfo); } } } if (filterAppList.size() == 0) { tvEmpty.setVisibility(View.VISIBLE); listView.setVisibility(View.GONE); tvEmpty.setText("没有任何数据"); } else { tvEmpty.setVisibility(View.GONE); listView.setVisibility(View.VISIBLE); appListAdapter.notifyDataSetChanged(); } //更新完成后 开放 按钮 btnScan.setEnabled(true); } }); } }.start(); } }); appListAdapter = new BaseAdapter() { @Override public int getCount() { return filterAppList.size(); } @Override public Object getItem(int position) { return filterAppList.get(position); } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = View.inflate(MainActivity.this, R.layout.item, null); holder = new ViewHolder(convertView); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } SimpleAppInfo appInfo = filterAppList.get(position); holder.tvAppPackage.setText(appInfo.getAppPackage()); if (switchType.isChecked()) { //这里是直接展示appInfo提供的 应用名\包名\Icon holder.tvAppName.setText(appInfo.getAppName()); holder.ivAppImage.setImageDrawable(appInfo.getAppIcon()); } else { //使用 指定资源数据 holder.tvAppName.setText(appInfo.getValuesAppName()); holder.ivAppImage.setImageDrawable(appInfo.getDrawablePreiewImg()); } return convertView; } }; listView.setAdapter(appListAdapter); } public static class ViewHolder { TextView tvAppName; TextView tvAppPackage; ImageView ivAppImage; public ViewHolder(View view) { tvAppName = view.findViewById(R.id.tv_app_name); tvAppPackage = view.findViewById(R.id.tv_app_package); ivAppImage = view.findViewById(R.id.iv_app_icon); } } public List<SimpleAppInfo> getAppsInfo() { List<SimpleAppInfo> list = new ArrayList<>(); PackageManager pm = getPackageManager(); if (pm == null) return list; List<PackageInfo> installedPackages = pm.getInstalledPackages(0); for (PackageInfo pi : installedPackages) { SimpleAppInfo ai = getBean(pm, pi); if (ai == null) continue; list.add(ai); } return list; } private SimpleAppInfo getBean(final PackageManager pm, final PackageInfo pi) { if (pi == null) return null; ApplicationInfo ai = pi.applicationInfo; String packageName = pi.packageName; String name = ai.loadLabel(pm).toString(); Drawable icon = ai.loadIcon(pm); String packagePath = ai.sourceDir; String versionName = pi.versionName; int versionCode = pi.versionCode; boolean isSystem = (ApplicationInfo.FLAG_SYSTEM & ai.flags) != 0; // return new SimpleAppInfo(packageName, name, icon, packagePath, versionName, versionCode, isSystem); SimpleAppInfo simpleAppInfo = new SimpleAppInfo(name, packageName, icon, isSystem, packagePath, versionName, versionCode); try { Resources resources = pm.getResourcesForApplication(packageName); int appNameId = resources.getIdentifier("app_name", "string", packageName); if (appNameId > 0) { String appName = resources.getString(appNameId); simpleAppInfo.setValuesAppName(appName); } int previewImgId = resources.getIdentifier("preview_img", "drawable", packageName); // int previewImgId = resources.getIdentifier("ic_launcher", "drawable", packageName); if (previewImgId > 0) { Drawable drawable = resources.getDrawable(previewImgId); simpleAppInfo.setDrawablePreiewImg(drawable); } } catch (Exception e) { e.printStackTrace(); } return simpleAppInfo; } }
所有代码均已贴出,并未使用任何第三方包,所以也就不上传demo了,
最后补充说明一下switch的作用
switch 开关 用于控制 显示 条目 内容
switch 开 -> 显示默认的appName 和appIcon
switch 关 -> 显示指定的 app_name和preview_img 资源
switch 关 -> 显示指定的 app_name和preview_img 资源
要是对你有帮助要关注我哦,我和其他人不一样,上代码就上全,绝不藏着掖着