package com.uiui.aios.utils; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Binder; import android.os.Build; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import androidx.annotation.RequiresApi; import com.uiui.aios.BuildConfig; import com.uiui.aios.R; import com.uiui.aios.bean.DesktopIcon; import com.uiui.aios.receiver.InstallResultReceiver; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.Collator; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.ObservableEmitter; import io.reactivex.rxjava3.core.ObservableOnSubscribe; import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.schedulers.Schedulers; public class ApkUtils { private static HashSet excludePackageName = new HashSet() {{ this.add(BuildConfig.APPLICATION_ID); this.add("org.chromium.browser"); this.add("com.sprd.sprdnote"); this.add("com.android.deskclock"); this.add("com.android.email"); // this.add("com.android.calendar"); this.add("com.android.uiuios"); this.add("com.uiui.os"); this.add("com.uiui.health"); this.add("com.uiui.appstore"); // this.add("com.tencent.android.qqdownloader"); // this.add("com.alldocube.store"); }}; private static HashSet showPackageName = new HashSet() {{ this.add("com.uiui.sn"); this.add("com.android.dialer"); this.add("com.android.gallery3d"); this.add("com.android.settings"); this.add("com.android.messaging"); this.add("com.android.camera2"); this.add("com.mediatek.camera"); this.add("com.android.mms"); this.add("com.uiui.city"); this.add("com.android.fmradio"); this.add("com.android.documentsui"); this.add("com.android.calculator2"); this.add("cn.wps.moffice_eng"); this.add("com.baidu.searchbox.lite"); this.add("com.ss.android.article.video"); this.add("com.ss.android.ugc.aweme"); this.add("com.smile.gifmaker"); this.add("com.kuaikan.comic"); this.add("com.jxw.launcher"); this.add("com.tencent.android.qqdownloader"); this.add("com.alldocube.store"); this.add("com.android.calendar"); }}; private static HashSet allHintPackage = new HashSet() {{ this.add("com.android.uiuios"); }}; private static String TAG = ApkUtils.class.getSimpleName(); public static ArrayList getSystemApp(Context context) { PackageManager pm = context.getPackageManager(); // 查询所有已经安装的应用程序 List appInfos = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);// GET_UNINSTALLED_PACKAGES代表已删除,但还有安装目录的 ArrayList applicationInfos = new ArrayList<>(); // 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER); // 通过getPackageManager()的queryIntentActivities方法遍历,得到所有能打开的app的packageName List resolveinfoList = pm.queryIntentActivities(resolveIntent, 0); Set allowPackages = new HashSet(); for (ResolveInfo resolveInfo : resolveinfoList) { Log.i(TAG, "queryFilterAppInfo: " + resolveInfo.activityInfo.packageName); allowPackages.add(resolveInfo.activityInfo.packageName); } for (ApplicationInfo app : appInfos) { if (allHintPackage.contains(app.packageName)) continue; if ((app.flags & ApplicationInfo.FLAG_SYSTEM) > 0) { if (allowPackages.contains(app.packageName) && !showPackageName.contains(app.packageName)) { applicationInfos.add(app); Log.e(TAG, "getSystemApp: " + app.packageName); } } } applicationInfos.sort(new Comparator() { @Override public int compare(ApplicationInfo o1, ApplicationInfo o2) { return Collator.getInstance(Locale.CHINESE).compare(o1.loadLabel(pm).toString(), o2.loadLabel(pm).toString()); // return o1.loadLabel(pm).toString().compareTo(o2.loadLabel(pm).toString()); } }); applicationInfos.sort(new Comparator() { @Override public int compare(ApplicationInfo o1, ApplicationInfo o2) { if ((o1.flags & ApplicationInfo.FLAG_SYSTEM) <= (o2.flags & ApplicationInfo.FLAG_SYSTEM)) { return 1; } else { return -1; } } }); return applicationInfos; } private static List defaultSort = new ArrayList() {{ this.add("com.android.dialer"); this.add("com.android.messaging"); this.add("com.android.gallery3d"); this.add("com.android.camera2"); this.add("com.android.settings"); this.add("com.uiui.sn"); this.add("com.uiui.appstore"); }}; /** * @param context * @return */ public static ArrayList queryFilterAppInfo(Context context) { PackageManager pm = context.getPackageManager(); // 查询所有已经安装的应用程序 List resolveInfos = new ArrayList<>(); // 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER); // 通过getPackageManager()的queryIntentActivities方法遍历,得到所有能打开的app的packageName List resolveinfoList = pm.queryIntentActivities(resolveIntent, 0); Set allowPackages = new HashSet(); for (ResolveInfo resolveInfo : resolveinfoList) { Log.i(TAG, "queryFilterAppInfo: " + resolveInfo.activityInfo.packageName); allowPackages.add(resolveInfo.activityInfo.packageName); } String appListString = Settings.System.getString(context.getContentResolver(), "only_jgy_shortcut_list"); List packageList = new ArrayList<>(); if (!TextUtils.isEmpty(appListString)) { packageList = new ArrayList<>(Arrays.asList(appListString.split(","))); } int setting_other_appInstaller = Settings.Global.getInt(context.getContentResolver(), "setting_other_appInstaller", 1); for (ResolveInfo resolveInfo : resolveinfoList) { String pkg = resolveInfo.activityInfo.packageName; if (appIsDisable(context, pkg)) { Log.e(TAG, "queryFilterAppInfo: disable = " + pkg); continue; } if (isSystemApp(context, pkg))//通过flag排除系统应用,会将电话、短信也排除掉 { if (showPackageName.contains(pkg)) { resolveInfos.add(resolveInfo); } } else { if (setting_other_appInstaller == 0) {//不显示自己安装的 if (packageList.contains(pkg)) { resolveInfos.add(resolveInfo); } } else { if (allowPackages.contains(pkg) && !excludePackageName.contains(pkg)) { resolveInfos.add(resolveInfo); } } } } if (Settings.Global.getInt(context.getContentResolver(), "is_activity", 0) == 0) { resolveInfos.removeIf(resolveInfo -> "com.uiui.city".equals(resolveInfo.activityInfo.packageName)); // resolveInfos.removeIf(applicationInfo -> "com.uiui.sn".equals(applicationInfo.packageName)); } resolveInfos.sort(new Comparator() { @Override public int compare(ResolveInfo o1, ResolveInfo o2) { return Collator.getInstance(Locale.CHINESE).compare(o1.loadLabel(pm).toString(), o2.loadLabel(pm).toString()); // return o1.loadLabel(pm).toString().compareTo(o2.loadLabel(pm).toString()); } }); resolveInfos.sort(new Comparator() { @Override public int compare(ResolveInfo o1, ResolveInfo o2) { try { if ((pm.getApplicationInfo(o1.activityInfo.packageName, 0).flags & ApplicationInfo.FLAG_SYSTEM) <= (pm.getApplicationInfo(o2.activityInfo.packageName, 0).flags & ApplicationInfo.FLAG_SYSTEM)) { return 1; } else { return -1; } } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return -1; } }); ArrayList desktopIcons = new ArrayList<>(); for (ResolveInfo applicationInfo : resolveInfos) { desktopIcons.add(DesktopIcon.creatDesktopIcon(context, applicationInfo)); } DesktopIcon exitIcon = new DesktopIcon(); exitIcon.setIcon(context.getDrawable(R.drawable.exit_icon)); exitIcon.setLable("切换系统"); exitIcon.setPackageName("aios.exit"); desktopIcons.add(exitIcon); return desktopIcons; } public static boolean appIsDisable(Context context, String pkg) { PackageManager pm = context.getPackageManager(); return pm.getApplicationEnabledSetting(pkg) == PackageManager.COMPONENT_ENABLED_STATE_DISABLED; } public static boolean isSystemApp(Context context, String pkg) { PackageManager pm = context.getPackageManager(); ApplicationInfo applicationInfo = null; try { applicationInfo = pm.getApplicationInfo(pkg, 0); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } if (applicationInfo == null) return false; return (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) > 0; } public static boolean disableApp(Context context, String pkg) { PackageManager pm = context.getPackageManager(); try { pm.setApplicationEnabledSetting(pkg, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0); return true; } catch (Exception e) { return false; } } /** * 获取第三方应用 * * @param context * @return */ public static List queryFilterAppList(Context context) { PackageManager pm = context.getPackageManager(); // 查询所有已经安装的应用程序 List appInfos = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);// GET_UNINSTALLED_PACKAGES代表已删除,但还有安装目录的 List applicationInfos = new ArrayList<>(); for (ApplicationInfo app : appInfos) { // Log.e("queryFilterAppInfo", String.valueOf(app.flags)); // Log.e("queryFilterAppInfo", String.valueOf((app.flags & mask))); if ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 1) { //通过flag排除系统应用,会将电话、短信也排除掉 } else { applicationInfos.add(app.packageName); Log.e("queryFilterAppInfo", app.packageName); } } return applicationInfos; } public static PackageInfo getPackageInfo(Context context, String pkg) { PackageManager packageManager = context.getPackageManager(); PackageInfo packageInfo = null; try { packageInfo = packageManager.getPackageInfo(pkg, 0); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return packageInfo; } public static ApplicationInfo getApplicationInfo(Context context, String pkg) { PackageManager packageManager = context.getPackageManager(); ApplicationInfo applicationInfo = null; try { applicationInfo = packageManager.getApplicationInfo(pkg, 0); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return applicationInfo; } public static void openApp(Context context, String packageName) { Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName); if (intent != null) { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } } public static boolean openPackage(Context context, String packageName) { Context pkgContext = getPackageContext(context, packageName); Intent intent = getAppOpenIntentByPackageName(context, packageName); if (pkgContext != null && intent != null) { pkgContext.startActivity(intent); return true; } return false; } public static boolean openPackage(Context context, String packageName, String className) { if (TextUtils.isEmpty(className)) { return openPackage(context, packageName); } ComponentName cn = new ComponentName(packageName, className); Intent intent = new Intent(); intent.setComponent(cn); if (context != null) { context.startActivity(intent); return true; } return false; } public static Context getPackageContext(Context context, String packageName) { Context pkgContext = null; if (context.getPackageName().equals(packageName)) { pkgContext = context; } else { // 创建第三方应用的上下文环境 try { pkgContext = context.createPackageContext(packageName, Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } } return pkgContext; } public static Intent getAppOpenIntentByPackageName(Context context, String packageName) { //Activity完整名 String mainAct = null; //根据包名寻找 PackageManager pkgMag = context.getPackageManager(); Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_NEW_TASK); List list = pkgMag.queryIntentActivities(intent, PackageManager.GET_ACTIVITIES); for (int i = 0; i < list.size(); i++) { ResolveInfo info = list.get(i); if (info.activityInfo.packageName.equals(packageName)) { mainAct = info.activityInfo.name; break; } } if (TextUtils.isEmpty(mainAct)) { return null; } intent.setComponent(new ComponentName(packageName, mainAct)); return intent; } public static String getAPPVersionName(Context context, String packageName) { String versionName = "0"; if (TextUtils.isEmpty(packageName)) { return versionName; } PackageManager pm = context.getPackageManager(); try { PackageInfo packageInfo = pm.getPackageInfo(packageName, 0); versionName = packageInfo.versionName; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return versionName; } public static String getAppNameByPackage(Context context, String pkg) { PackageManager packageManager = context.getPackageManager(); try { ApplicationInfo applicationInfo = packageManager.getApplicationInfo(pkg, PackageManager.GET_META_DATA); String packageName = packageManager.getApplicationLabel(applicationInfo).toString(); return packageName; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return ""; } /** * 检查手机上是否安装了指定的软件 */ public static boolean isAvailable(Context context, String packageName) { PackageManager packageManager = context.getPackageManager(); PackageInfo info = null; try { info = packageManager.getPackageInfo(packageName, 0); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return info != null; } /** * 检查手机上是否安装了指定的软件 */ public static boolean isAvailable(Context context, File file) { return isAvailable(context, getPackageName(context, file.getAbsolutePath())); } /** * 根据文件路径获取包名 */ public static String getPackageName(Context context, String filePath) { PackageManager packageManager = context.getPackageManager(); PackageInfo info = packageManager.getPackageArchiveInfo(filePath, PackageManager.GET_ACTIVITIES); if (info != null) { ApplicationInfo appInfo = info.applicationInfo; return appInfo.packageName; //得到安装包名称 } else { return ""; } } /** * 静默卸载应用 * * @param context * @param pkg */ public static void UninstallAPP(Context context, String pkg) { Observable.create(new ObservableOnSubscribe() { @Override public void subscribe(ObservableEmitter emitter) throws Exception { Log.e("UninstallAPP", "call: " + Thread.currentThread().getName()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { ApkUtils.uninstall(context, pkg); } else { ApkUtils.deleteApkInSilence(pkg); } emitter.onNext(pkg); } }).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @Override public void onSubscribe(Disposable d) { Log.e("UninstallAPP", "onSubscribe: "); } @Override public void onNext(String s) { Log.e("UninstallAPP", "onNext: " + Thread.currentThread().getName()); Log.e("UninstallAPP", "onNext: " + s); } @Override public void onError(Throwable e) { Log.e("UninstallAPP", "onError: " + e.getMessage()); } @Override public void onComplete() { Log.e("UninstallAPP", "onComplete: "); } }); } /** * 根据包名卸载应用 * * @param packageName 包名 */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public static void uninstall(Context context, String packageName) { Intent broadcastIntent = new Intent(context, InstallResultReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT); PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller(); packageInstaller.uninstall(packageName, pendingIntent.getIntentSender()); } public static void deleteApkInSilence(String packageName) { Class pmService; Class activityTherad; Method method; try { activityTherad = Class.forName("android.app.ActivityThread"); Class paramTypes[] = getParamTypes(activityTherad, "getPackageManager"); method = activityTherad.getMethod("getPackageManager", paramTypes); Object PackageManagerService = method.invoke(activityTherad); pmService = PackageManagerService.getClass(); Class paramTypes1[] = getParamTypes(pmService, "deletePackageAsUser"); method = pmService.getMethod("deletePackageAsUser", paramTypes1); //getUserId method.invoke(PackageManagerService, packageName, null, getUserId(Binder.getCallingUid()), 0x00000040); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } private static Class[] getParamTypes(Class cls, String mName) { Class cs[] = null; Method[] mtd = cls.getMethods(); for (int i = 0; i < mtd.length; i++) { if (!mtd[i].getName().equals(mName)) { continue; } cs = mtd[i].getParameterTypes(); } return cs; } public static final int PER_USER_RANGE = 100000; public static int getUserId(int uid) { return uid / PER_USER_RANGE; } }