package com.huaye.odyandroidstore.utils; import android.annotation.SuppressLint; import android.app.Activity; import android.app.ActivityManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; import android.graphics.drawable.Drawable; import java.io.File; import java.util.ArrayList; import java.util.List; /** * <pre> * author: Blankj * blog : http://blankj.com * time : 2016/8/2 * desc : App相关工具类 * </pre> */ public class AppUtils { private AppUtils() { throw new UnsupportedOperationException("u can't instantiate me..."); } /** * 判断App是否安装 * * @param context 上下文 * @param packageName 包名 * @return {@code true}: 已安装<br>{@code false}: 未安装 */ public static boolean isInstallApp(Context context, String packageName) { return !StringUtils.isSpace(packageName) && IntentUtils.getLaunchAppIntent(packageName) != null; } /** * 安装App(支持6.0) * * @param context 上下文 * @param filePath 文件路径 */ public static void installApp(Context context, String filePath) { installApp(context, FileUtils.getFileByPath(filePath)); } /** * 安装App(支持6.0) * * @param context 上下文 * @param file 文件 */ public static void installApp(Context context, File file) { if (!FileUtils.isFileExists(file)) return; context.startActivity(IntentUtils.getInstallAppIntent(file)); } /** * 安装App(支持6.0) * * @param activity activity * @param filePath 文件路径 * @param requestCode 请求值 */ public static void installApp(Activity activity, String filePath, int requestCode) { installApp(activity, FileUtils.getFileByPath(filePath), requestCode); } /** * 安装App(支持6.0) * * @param activity activity * @param file 文件 * @param requestCode 请求值 */ public static void installApp(Activity activity, File file, int requestCode) { if (!FileUtils.isFileExists(file)) return; activity.startActivityForResult(IntentUtils.getInstallAppIntent(file), requestCode); } /** * 静默安装App * <p>非root需添加权限 {@code <uses-permission android:name="android.permission.INSTALL_PACKAGES" />}</p> * * @param filePath 文件路径 * @return {@code true}: 安装成功<br>{@code false}: 安装失败 */ public static boolean installAppSilent(String filePath) { File file = FileUtils.getFileByPath(filePath); if (!FileUtils.isFileExists(file)) return false; String command = "LD_LIBRARY_PATH=/vendor/lib:/system/lib pm install " + filePath; ShellUtils.CommandResult commandResult = ShellUtils.execCmd(command, !isSystemApp(Utils.getContext()), true); return commandResult.successMsg != null && commandResult.successMsg.toLowerCase().contains("success"); } /** * 卸载App * * @param context 上下文 * @param packageName 包名 */ public static void uninstallApp(Context context, String packageName) { if (StringUtils.isSpace(packageName)) return; context.startActivity(IntentUtils.getUninstallAppIntent(packageName)); } /** * 卸载App * * @param activity activity * @param packageName 包名 * @param requestCode 请求值 */ public static void uninstallApp(Activity activity, String packageName, int requestCode) { if (StringUtils.isSpace(packageName)) return; activity.startActivityForResult(IntentUtils.getUninstallAppIntent(packageName), requestCode); } /** * 静默卸载App * <p>非root需添加权限 {@code <uses-permission android:name="android.permission.DELETE_PACKAGES" />}</p> * * @param context 上下文 * @param packageName 包名 * @param isKeepData 是否保留数据 * @return {@code true}: 卸载成功<br>{@code false}: 卸载成功 */ public static boolean uninstallAppSilent(Context context, String packageName, boolean isKeepData) { if (StringUtils.isSpace(packageName)) return false; String command = "LD_LIBRARY_PATH=/vendor/lib:/system/lib pm uninstall " + (isKeepData ? "-k " : "") + packageName; ShellUtils.CommandResult commandResult = ShellUtils.execCmd(command, !isSystemApp(context), true); return commandResult.successMsg != null && commandResult.successMsg.toLowerCase().contains("success"); } /** * 判断App是否有root权限 * * @return {@code true}: 是<br>{@code false}: 否 */ public static boolean isAppRoot() { ShellUtils.CommandResult result = ShellUtils.execCmd("echo root", true); if (result.result == 0) { return true; } if (result.errorMsg != null) { LogUtils.d("isAppRoot", result.errorMsg); } return false; } /** * 打开App * * @param packageName 包名 */ public static void launchApp(String packageName) { if (StringUtils.isSpace(packageName)) return; Utils.getContext().startActivity(IntentUtils.getLaunchAppIntent(packageName)); } /** * 打开App * * @param activity activity * @param packageName 包名 * @param requestCode 请求值 */ public static void launchApp(Activity activity, String packageName, int requestCode) { if (StringUtils.isSpace(packageName)) return; activity.startActivityForResult(IntentUtils.getLaunchAppIntent(packageName), requestCode); } /** * 获取App包名 * * @param context 上下文 * @return App包名 */ public static String getAppPackageName(Context context) { return context.getPackageName(); } /** * 获取App具体设置 * * @param context 上下文 */ public static void getAppDetailsSettings(Context context) { getAppDetailsSettings(context, context.getPackageName()); } /** * 获取App具体设置 * * @param context 上下文 * @param packageName 包名 */ public static void getAppDetailsSettings(Context context, String packageName) { if (StringUtils.isSpace(packageName)) return; context.startActivity(IntentUtils.getAppDetailsSettingsIntent(packageName)); } /** * 获取App名称 * * @param context 上下文 * @return App名称 */ public static String getAppName(Context context) { return getAppName(context, context.getPackageName()); } /** * 获取App名称 * * @param context 上下文 * @param packageName 包名 * @return App名称 */ public static String getAppName(Context context, String packageName) { if (StringUtils.isSpace(packageName)) return null; try { PackageManager pm = context.getPackageManager(); PackageInfo pi = pm.getPackageInfo(packageName, 0); return pi == null ? null : pi.applicationInfo.loadLabel(pm).toString(); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return null; } } /** * 获取App图标 * * @param context 上下文 * @return App图标 */ public static Drawable getAppIcon(Context context) { return getAppIcon(context, context.getPackageName()); } /** * 获取App图标 * * @param context 上下文 * @param packageName 包名 * @return App图标 */ public static Drawable getAppIcon(Context context, String packageName) { if (StringUtils.isSpace(packageName)) return null; try { PackageManager pm = context.getPackageManager(); PackageInfo pi = pm.getPackageInfo(packageName, 0); return pi == null ? null : pi.applicationInfo.loadIcon(pm); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return null; } } /** * 获取App路径 * * @param context 上下文 * @return App路径 */ public static String getAppPath(Context context) { return getAppPath(context, context.getPackageName()); } /** * 获取App路径 * * @param context 上下文 * @param packageName 包名 * @return App路径 */ public static String getAppPath(Context context, String packageName) { if (StringUtils.isSpace(packageName)) return null; try { PackageManager pm = context.getPackageManager(); PackageInfo pi = pm.getPackageInfo(packageName, 0); return pi == null ? null : pi.applicationInfo.sourceDir; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return null; } } /** * 获取App版本号 * * @param context 上下文 * @return App版本号 */ public static String getAppVersionName(Context context) { return getAppVersionName(context, context.getPackageName()); } /** * 获取App版本号 * * @param context 上下文 * @param packageName 包名 * @return App版本号 */ public static String getAppVersionName(Context context, String packageName) { if (StringUtils.isSpace(packageName)) return null; try { PackageManager pm = context.getPackageManager(); PackageInfo pi = pm.getPackageInfo(packageName, 0); return pi == null ? null : pi.versionName; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return null; } } /** * 获取App版本码 * * @param context 上下文 * @return App版本码 */ public static int getAppVersionCode(Context context) { return getAppVersionCode(context, context.getPackageName()); } /** * 获取App版本码 * * @param context 上下文 * @param packageName 包名 * @return App版本码 */ public static int getAppVersionCode(Context context, String packageName) { if (StringUtils.isSpace(packageName)) return -1; try { PackageManager pm = context.getPackageManager(); PackageInfo pi = pm.getPackageInfo(packageName, 0); return pi == null ? -1 : pi.versionCode; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return -1; } } /** * 判断App是否是系统应用 * * @param context 上下文 * @return {@code true}: 是<br>{@code false}: 否 */ public static boolean isSystemApp(Context context) { return isSystemApp(context, context.getPackageName()); } /** * 判断App是否是系统应用 * * @param context 上下文 * @param packageName 包名 * @return {@code true}: 是<br>{@code false}: 否 */ public static boolean isSystemApp(Context context, String packageName) { if (StringUtils.isSpace(packageName)) return false; try { PackageManager pm = context.getPackageManager(); ApplicationInfo ai = pm.getApplicationInfo(packageName, 0); return ai != null && (ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return false; } } /** * 判断App是否是Debug版本 * * @param context 上下文 * @return {@code true}: 是<br>{@code false}: 否 */ public static boolean isAppDebug(Context context) { return isAppDebug(context, context.getPackageName()); } /** * 判断App是否是Debug版本 * * @param context 上下文 * @param packageName 包名 * @return {@code true}: 是<br>{@code false}: 否 */ public static boolean isAppDebug(Context context, String packageName) { if (StringUtils.isSpace(packageName)) return false; try { PackageManager pm = context.getPackageManager(); ApplicationInfo ai = pm.getApplicationInfo(packageName, 0); return ai != null && (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return false; } } /** * 获取App签名 * * @param context 上下文 * @return App签名 */ public static Signature[] getAppSignature(Context context) { return getAppSignature(context, context.getPackageName()); } /** * 获取App签名 * * @param context 上下文 * @param packageName 包名 * @return App签名 */ @SuppressLint("PackageManagerGetSignatures") public static Signature[] getAppSignature(Context context, String packageName) { if (StringUtils.isSpace(packageName)) return null; try { PackageManager pm = context.getPackageManager(); PackageInfo pi = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); return pi == null ? null : pi.signatures; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return null; } } /** * 获取应用签名的的SHA1值 * <p>可据此判断高德,百度地图key是否正确</p> * * @param context 上下文 * @return 应用签名的SHA1字符串, 比如:53:FD:54:DC:19:0F:11:AC:B5:22:9E:F1:1A:68:88:1B:8B:E8:54:42 */ public static String getAppSignatureSHA1(Context context) { return getAppSignatureSHA1(context, context.getPackageName()); } /** * 获取应用签名的的SHA1值 * <p>可据此判断高德,百度地图key是否正确</p> * * @param context 上下文 * @param packageName 包名 * @return 应用签名的SHA1字符串, 比如:53:FD:54:DC:19:0F:11:AC:B5:22:9E:F1:1A:68:88:1B:8B:E8:54:42 */ public static String getAppSignatureSHA1(Context context, String packageName) { Signature[] signature = getAppSignature(context, packageName); if (signature == null) return null; return EncryptUtils.encryptSHA1ToString(signature[0].toByteArray()). replaceAll("(?<=[0-9A-F]{2})[0-9A-F]{2}", ":$0"); } /** * 判断App是否处于前台 * * @param context 上下文 * @return {@code true}: 是<br>{@code false}: 否 */ public static boolean isAppForeground(Context context) { ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningAppProcessInfo> infos = manager.getRunningAppProcesses(); if (infos == null || infos.size() == 0) return false; for (ActivityManager.RunningAppProcessInfo info : infos) { if (info.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { return info.processName.equals(context.getPackageName()); } } return false; } /** * 判断App是否处于前台 * <p>当不是查看当前App,且SDK大于21时, * 需添加权限 {@code <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>}</p> * * @param context 上下文 * @param packageName 包名 * @return {@code true}: 是<br>{@code false}: 否 */ public static boolean isAppForeground(Context context, String packageName) { return !StringUtils.isSpace(packageName) && packageName.equals(ProcessUtils.getForegroundProcessName()); } /** * 封装App信息的Bean类 */ public static class AppInfo { private String name; private Drawable icon; private String packageName; private String packagePath; private String versionName; private int versionCode; private boolean isSystem; public Drawable getIcon() { return icon; } public void setIcon(Drawable icon) { this.icon = icon; } public boolean isSystem() { return isSystem; } public void setSystem(boolean isSystem) { this.isSystem = isSystem; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPackageName() { return packageName; } public void setPackageName(String packagName) { this.packageName = packagName; } public String getPackagePath() { return packagePath; } public void setPackagePath(String packagePath) { this.packagePath = packagePath; } public int getVersionCode() { return versionCode; } public void setVersionCode(int versionCode) { this.versionCode = versionCode; } public String getVersionName() { return versionName; } public void setVersionName(String versionName) { this.versionName = versionName; } /** * @param name 名称 * @param icon 图标 * @param packageName 包名 * @param packagePath 包路径 * @param versionName 版本号 * @param versionCode 版本码 * @param isSystem 是否系统应用 */ public AppInfo(String packageName, String name, Drawable icon, String packagePath, String versionName, int versionCode, boolean isSystem) { this.setName(name); this.setIcon(icon); this.setPackageName(packageName); this.setPackagePath(packagePath); this.setVersionName(versionName); this.setVersionCode(versionCode); this.setSystem(isSystem); } @Override public String toString() { return "App包名:" + getPackageName() + "\nApp名称:" + getName() + "\nApp图标:" + getIcon() + "\nApp路径:" + getPackagePath() + "\nApp版本号:" + getVersionName() + "\nApp版本码:" + getVersionCode() + "\n是否系统App:" + isSystem(); } } /** * 获取App信息 * <p>AppInfo(名称,图标,包名,版本号,版本Code,是否系统应用)</p> * * @param context 上下文 * @return 当前应用的AppInfo */ public static AppInfo getAppInfo(Context context) { return getAppInfo(context, context.getPackageName()); } /** * 获取App信息 * <p>AppInfo(名称,图标,包名,版本号,版本Code,是否系统应用)</p> * * @param context 上下文 * @param packageName 包名 * @return 当前应用的AppInfo */ public static AppInfo getAppInfo(Context context, String packageName) { try { PackageManager pm = context.getPackageManager(); PackageInfo pi = pm.getPackageInfo(packageName, 0); return getBean(pm, pi); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return null; } } /** * 得到AppInfo的Bean * * @param pm 包的管理 * @param pi 包的信息 * @return AppInfo类 */ private static AppInfo getBean(PackageManager pm, PackageInfo pi) { if (pm == null || 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 AppInfo(packageName, name, icon, packagePath, versionName, versionCode, isSystem); } /** * 获取所有已安装App信息 * <p>{@link #getBean(PackageManager, PackageInfo)}(名称,图标,包名,包路径,版本号,版本Code,是否系统应用)</p> * <p>依赖上面的getBean方法</p> * * @param context 上下文 * @return 所有已安装的AppInfo列表 */ public static List<AppInfo> getAppsInfo(Context context) { List<AppInfo> list = new ArrayList<>(); PackageManager pm = context.getPackageManager(); // 获取系统中安装的所有软件信息 List<PackageInfo> installedPackages = pm.getInstalledPackages(0); for (PackageInfo pi : installedPackages) { AppInfo ai = getBean(pm, pi); if (ai == null) continue; list.add(ai); } return list; } /** * 清除App所有数据 * * @param context 上下文 * @param dirPaths 目录路径 * @return {@code true}: 成功<br>{@code false}: 失败 */ public static boolean cleanAppData(Context context, String... dirPaths) { File[] dirs = new File[dirPaths.length]; int i = 0; for (String dirPath : dirPaths) { dirs[i++] = new File(dirPath); } return cleanAppData(dirs); } /** * 清除App所有数据 * * @param dirs 目录 * @return {@code true}: 成功<br>{@code false}: 失败 */ public static boolean cleanAppData(File... dirs) { boolean isSuccess = CleanUtils.cleanInternalCache(); isSuccess &= CleanUtils.cleanInternalDbs(); isSuccess &= CleanUtils.cleanInternalSP(); isSuccess &= CleanUtils.cleanInternalFiles(); isSuccess &= CleanUtils.cleanExternalCache(); for (File dir : dirs) { isSuccess &= CleanUtils.cleanCustomCache(dir); } return isSuccess; } }