工具类之AppUtils

作者: Blankj | 来源:发表于2016-09-29 16:45 被阅读7074次

    花了好大劲总算整理完了应用相关的工具类,老司机没时间多说了,发车~~

    isInstallApp          : 判断App是否安装
    installApp            : 安装App(支持6.0)
    installAppSilent      : 静默安装App
    uninstallApp          : 卸载App
    uninstallAppSilent    : 静默卸载App
    isAppRoot             : 判断App是否有root权限
    launchApp             : 打开App
    closeApp              : 关闭App
    getAppPackageName     : 获取App包名
    getAppDetailsSettings : 获取App具体设置
    getAppName            : 获取App名称
    getAppIcon            : 获取App图标
    getAppPath            : 获取App路径
    getAppVersionName     : 获取App版本号
    getAppVersionCode     : 获取App版本码
    isSystemApp           : 判断App是否是系统应用
    isAppDebug            : 判断App是否是Debug版本
    getAppSignature       : 获取App签名
    getAppSignatureSHA1   : 获取应用签名的的SHA1值
    isAppForeground       : 判断App是否处于前台
    getForegroundApp      : 获取前台应用包名
    getAppInfo            : 获取App信息
    getAppsInfo           : 获取所有已安装App信息
    cleanAppData          : 清除App所有数据
    

    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.Arrays;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    
    /**
     * <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(context, 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 context  上下文
         * @param filePath 文件路径
         * @return {@code true}: 安装成功<br>{@code false}: 安装失败
         */
        public static boolean installAppSilent(Context context, 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(context), 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 context     上下文
         * @param packageName 包名
         */
        public static void launchApp(Context context, String packageName) {
            if (StringUtils.isSpace(packageName)) return;
            context.startActivity(IntentUtils.getLaunchAppIntent(context, 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(activity, 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(context));
        }
    
        /**
         * 封装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(context, dirs);
        }
    
        /**
         * 清除App所有数据
         *
         * @param context 上下文
         * @param dirs    目录
         * @return {@code true}: 成功<br>{@code false}: 失败
         */
        public static boolean cleanAppData(Context context, File... dirs) {
            boolean isSuccess = CleanUtils.cleanInternalCache(context);
            isSuccess &= CleanUtils.cleanInternalDbs(context);
            isSuccess &= CleanUtils.cleanInternalSP(context);
            isSuccess &= CleanUtils.cleanInternalFiles(context);
            isSuccess &= CleanUtils.cleanExternalCache(context);
            for (File dir : dirs) {
                isSuccess &= CleanUtils.cleanCustomCache(dir);
            }
            return isSuccess;
        }
    }
    

    如果该工具类依赖其他工具类,都可以在我的Android开发人员不得不收集的代码(持续更新中)中找到。

    相关文章

      网友评论

      • 96ee612940ce:静默安装那块我试过,用tcl电视和智能魔镜试的,不行。后来又找了一个PackageUtils 可以实现静默安装,能不能把静默安装在优化优化
      • wo叫天然呆: /**
        * 获取application中指定的meta-data
        *
        * @param ctx
        * @param key
        * @Return 如果没有获取成功(没有对应值,或者异常),则返回值为空
        */
        public static String getAppMetaData(Context ctx, String key) {
        //key = "UMENG_CHANNEL";
        if (ctx == null || TextUtils.isEmpty(key)) {
        return null;
        }
        String resultData = null;
        try {
        PackageManager pm = ctx.getPackageManager();
        if (pm != null) {
        ApplicationInfo applicationInfo = pm.getApplicationInfo(
        ctx.getPackageName(), PackageManager.GET_META_DATA);
        if (applicationInfo != null) {
        if (applicationInfo.metaData != null) {
        resultData = applicationInfo.metaData.getString(key);
        }
        }
        }
        } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
        }
        return resultData;
        }
      • 秃渐强:谢谢:pray:
      • wo叫天然呆:/**
        * 通过任务管理器杀死进程
        * 需添加权限 {@code <uses-permission android:name="android.permission.RESTART_PACKAGES"/>}</p>
        *
        * @param context
        */
        public static void restart(Context context) {
        int currentVersion = android.os.Build.VERSION.SDK_INT;
        if (currentVersion > android.os.Build.VERSION_CODES.ECLAIR_MR1) {
        Intent startMain = new Intent(Intent.ACTION_MAIN);
        startMain.addCategory(Intent.CATEGORY_HOME);
        startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(startMain);
        System.exit(0);
        } else {// android2.1
        ActivityManager am = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
        am.restartPackage(context.getPackageName());
        }
        }
        关闭APP,不知道是否有价值
      • 2a26daa82f86:老司机 带带我
      • CokeNello:额,在家里上不了Github,之前从楼主的github下载了整套的Utils,真心佩服楼主!
        不过我好像发现了一个bug:
        CameraUtils - getChoosedImagePath 方法中,最后一行:
        return StringUtils.isEmpty(path) ? originalUri.getPath() : null;
        是错了吧?当,path不为空的时候,却返回 null ?
        应该是:
        return StringUtils.isEmpty(path) ? originalUri.getPath() : path;
        :smile: 还有,choose的过去式是:chosen,哈哈~
        CokeNello:@Blankj 加油,我也在修改,哈哈,期待你的发布!
        Blankj:@栗子酱plus 那个还没修正呢,是别人pr的,我copy的,我下个版本才会发布它
      • ce36c3e26e04:学习下!
      • fendo:赞一个!!
      • Blankj:6666666 我都没发布呢

      本文标题:工具类之AppUtils

      本文链接:https://www.haomeiwen.com/subject/flihyttx.html