关于 java+gradle的弹窗多选应用app

已过滤系统应用

java 复制代码
package com.example.skipAd;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;

import androidx.appcompat.app.AlertDialog;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * App 选择器工具类(支持多选 + 本地保存 + 回显)
 */
public class AppChooserHelper {

    private final Context context;
    private final SharedPreferences prefs;
    private final String prefsKey;

    private List<String> appNames;
    private List<String> packageNames;

    public interface OnAppsSelectedListener {
        void onAppsSelected(Set<String> selectedApps);
    }

    /**
     * @param context   Activity 或 Application Context
     * @param prefsName SharedPreferences 名称
     * @param prefsKey  保存选择的 key
     */
    public AppChooserHelper(Context context, String prefsName, String prefsKey) {
        this.context = context;
        this.prefs = context.getSharedPreferences(prefsName, Context.MODE_PRIVATE);
        this.prefsKey = prefsKey;
    }

    /**
     * 显示多选 App 弹窗
     */
    public void showAppChooserDialog(final OnAppsSelectedListener listener) {
        final PackageManager pm = context.getPackageManager();
        List<ApplicationInfo> apps = pm.getInstalledApplications(PackageManager.GET_META_DATA);

        final Set<String> savedApps = prefs.getStringSet(prefsKey, new HashSet<>());
        final Set<String> selectedApps = new HashSet<>(savedApps);

        List<String> selectedAppNames = new ArrayList<>();
        List<String> otherAppNames = new ArrayList<>();
        List<String> selectedPackageNames = new ArrayList<>();
        List<String> otherPackageNames = new ArrayList<>();

        for (ApplicationInfo app : apps) {
            // 只显示可启动的第三方应用
            if (pm.getLaunchIntentForPackage(app.packageName) != null
                    && (app.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {

                String name = app.loadLabel(pm).toString();
                String pkg = app.packageName;

                if (savedApps.contains(name)) {
                    selectedAppNames.add(name);
                    selectedPackageNames.add(pkg);
                } else {
                    otherAppNames.add(name);
                    otherPackageNames.add(pkg);
                }
            }
        }

        // 合并:已选择应用在前
        appNames = new ArrayList<>();
        appNames.addAll(selectedAppNames);
        appNames.addAll(otherAppNames);

        packageNames = new ArrayList<>();
        packageNames.addAll(selectedPackageNames);
        packageNames.addAll(otherPackageNames);

        // checkedItems 逻辑保持不变
        boolean[] checkedItems = new boolean[appNames.size()];
        for (int i = 0; i < appNames.size(); i++) {
            checkedItems[i] = savedApps.contains(appNames.get(i));
        }

        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle("选择应用")
                .setMultiChoiceItems(appNames.toArray(new String[0]), checkedItems,
                        (dialog, which, isChecked) -> {
                            if (isChecked) {
                                selectedApps.add(appNames.get(which));
                            } else {
                                selectedApps.remove(appNames.get(which));
                            }
                        })
                .setPositiveButton("确定", (dialog, which) -> {
                    prefs.edit().putStringSet(prefsKey, selectedApps).apply();
                    if (listener != null) {
                        listener.onAppsSelected(selectedApps);
                    }
                })
                .setNegativeButton("取消", null)
                .show();
    }

    /**
     * 获取已选择的应用(回显用)
     */
    public Set<String> getSelectedApps() {
        return prefs.getStringSet(prefsKey, new HashSet<>());
    }
}