美文网首页
Android 常用工具类之 AppUtils

Android 常用工具类之 AppUtils

作者: Kevin_小飞象 | 来源:发表于2021-03-31 08:47 被阅读0次
    每日一图.jpg

    APP 相关信息工具类,此工具类不是网上大家用烂的那一份,是博主亲自编写,亲自测试,代码简洁清晰,可满足日常开发。

    方法

    getVerCode()  :得到软件版本号
    getMaxMemory() :获取应用运行的最大内存
    getVerName() :得到软件显示版本信息
    installApk() :安装apk
    uninstallApk() :卸载apk
    isServiceRunning() :检测服务是否运行
    stopRunningService() :停止运行服务
    getNumCores() :得到CPU核心数
    isNamedProcess() :是否含有当前的进程
    isApplicationInBackground() :whether application is in background
    getSign() :获取应用签名
    hexdigest() :将签名字符串转换成需要的32位签名
    getDeviceUsableMemory() :获取设备的可用内存大小
    gc() :清理后台进程与服务
    getAllApps() :获取系统中所有的应用
    getSDKVersion() :获取手机系统SDK版本
    isDalvik() :是否Dalvik模式
    isART() :是否ART模式
    getCurrentRuntimeValue() :获取手机当前的Runtime
    isDebuggable() :检测当前应用是否是Debug版本
    compareVersion() :比较版本号的大小,前者大则返回一个正数,后者大返回一个负数,相等则返回0
    

    代码

    import java.io.ByteArrayInputStream;
    import java.io.File;
    
    import java.io.FileFilter;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.security.MessageDigest;
    import java.security.cert.CertificateException;
    import java.security.cert.CertificateFactory;
    import java.security.cert.X509Certificate;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.regex.Pattern;
    import android.app.ActivityManager;
    import android.app.ActivityManager.MemoryInfo;
    import android.app.ActivityManager.RunningAppProcessInfo;
    import android.app.ActivityManager.RunningServiceInfo;
    import android.app.ActivityManager.RunningTaskInfo;
    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.PackageManager;
    import android.content.pm.PackageManager.NameNotFoundException;
    import android.content.pm.Signature;
    import android.net.Uri;
    import android.os.Build;
    import android.text.TextUtils;
    
    import androidx.core.content.FileProvider;
    
    import javax.security.auth.x500.X500Principal;
    
    /**
     * Created on 2021/3/30 18:08
     *
     * @author Gong Youqiang
     */
    public final class AppUtils {
        private static final boolean DEBUG = true;
        private static final String TAG = "AppUtils";
    
    
        /**
         * Don't let anyone instantiate this class.
         */
        private AppUtils() {
            throw new Error("Do not need instantiate!");
        }
    
        /**
         * 得到软件版本号
         *
         * @param context 上下文
         * @return 当前版本Code
         */
        public static int getVerCode(Context context) {
            int verCode = -1;
            try {
                String packageName = context.getPackageName();
                verCode = context.getPackageManager()
                        .getPackageInfo(packageName, 0).versionCode;
            } catch (NameNotFoundException e) {
                e.printStackTrace();
            }
            return verCode;
        }
    
        /**
         * 获取应用运行的最大内存
         *
         * @return 最大内存
         */
        public static long getMaxMemory() {
    
            return Runtime.getRuntime().maxMemory() / 1024;
        }
    
        /**
         * 得到软件显示版本信息
         *
         * @param context 上下文
         * @return 当前版本信息
         */
        public static String getVerName(Context context) {
            String verName = "";
            try {
                String packageName = context.getPackageName();
                verName = context.getPackageManager()
                        .getPackageInfo(packageName, 0).versionName;
            } catch (NameNotFoundException e) {
                e.printStackTrace();
            }
            return verName;
        }
    
        /**
         * 安装apk
         * Android 7.0 或更高版本的应用私有目录被限制访问
         * @param context 上下文
         * @param file    APK文件
         * @paras authority provider->authority属性
         */
        public void installApk(Context context, File file, String authority) {
            Intent intent = new Intent();
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setAction(Intent.ACTION_VIEW);
            intent.setDataAndType(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N ? FileProvider.getUriForFile(context,authority,file):
                    Uri.fromFile(file),"\"application/vnd.android.package-archive\"");
            context.startActivity(intent);
        }
    
        /**
         * 卸载apk
         *
         * @param context     上下文
         * @param packageName 包名
         */
        public static void uninstallApk(Context context, String packageName) {
            Intent intent = new Intent(Intent.ACTION_DELETE);
            Uri packageURI = Uri.parse("package:" + packageName);
            intent.setData(packageURI);
            context.startActivity(intent);
        }
    
        /**
         * 检测服务是否运行
         *
         * @param context   上下文
         * @param className 类名
         * @return 是否运行的状态
         */
        public static boolean isServiceRunning(Context context, String className) {
            boolean isRunning = false;
            ActivityManager activityManager
                    = (ActivityManager) context.getSystemService(
                    Context.ACTIVITY_SERVICE);
            List<RunningServiceInfo> servicesList
                    = activityManager.getRunningServices(Integer.MAX_VALUE);
            for (RunningServiceInfo si : servicesList) {
                if (className.equals(si.service.getClassName())) {
                    isRunning = true;
                }
            }
            return isRunning;
        }
    
        /**
         * 停止运行服务
         *
         * @param context   上下文
         * @param className 类名
         * @return 是否执行成功
         */
        public static boolean stopRunningService(Context context, String className) {
            Intent intent_service = null;
            boolean ret = false;
            try {
                intent_service = new Intent(context, Class.forName(className));
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (intent_service != null) {
                ret = context.stopService(intent_service);
            }
            return ret;
        }
    
        /**
         * 得到CPU核心数
         *
         * @return CPU核心数
         */
        public static int getNumCores() {
            try {
                File dir = new File("/sys/devices/system/cpu/");
                File[] files = dir.listFiles(new FileFilter() {
                    @Override public boolean accept(File pathname) {
                        if (Pattern.matches("cpu[0-9]", pathname.getName())) {
                            return true;
                        }
                        return false;
                    }
                });
                return files.length;
            } catch (Exception e) {
                return 1;
            }
        }
    
        /**
         * whether this process is named with processName
         *
         * @param context     上下文
         * @param processName 进程名
         * @return 是否含有当前的进程
         */
        public static boolean isNamedProcess(Context context, String processName) {
            if (context == null || TextUtils.isEmpty(processName)) {
                return false;
            }
    
            int pid = android.os.Process.myPid();
            ActivityManager manager = (ActivityManager) context.getSystemService(
                    Context.ACTIVITY_SERVICE);
            List<RunningAppProcessInfo> processInfoList
                    = manager.getRunningAppProcesses();
            if (processInfoList == null) {
                return true;
            }
    
            for (RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
                if (processInfo.pid == pid &&
                        processName.equalsIgnoreCase(processInfo.processName)) {
                    return true;
                }
            }
            return false;
        }
    
        /**
         * whether application is in background
         * <ul>
         * <li>need use permission android.permission.GET_TASKS in Manifest.xml</li>
         * </ul>
         *
         * @param context 上下文
         * @return if application is in background return true, otherwise return
         * false
         */
        public static boolean isApplicationInBackground(Context context) {
            ActivityManager am = (ActivityManager) context.getSystemService(
                    Context.ACTIVITY_SERVICE);
            List<RunningTaskInfo> taskList = am.getRunningTasks(1);
            if (taskList != null && !taskList.isEmpty()) {
                ComponentName topActivity = taskList.get(0).topActivity;
                if (topActivity != null && !topActivity.getPackageName()
                        .equals(context.getPackageName())) {
                    return true;
                }
            }
            return false;
        }
    
        /**
         * 获取应用签名
         *
         * @param context 上下文
         * @param pkgName 包名
         * @return 返回应用的签名
         */
        public static String getSign(Context context, String pkgName) {
            try {
                PackageInfo pis = context.getPackageManager()
                        .getPackageInfo(pkgName,
                                PackageManager.GET_SIGNATURES);
                return hexdigest(pis.signatures[0].toByteArray());
            } catch (NameNotFoundException e) {
                e.printStackTrace();
                return null;
            }
    
        }
    
        /**
         * 将签名字符串转换成需要的32位签名
         *
         * @param paramArrayOfByte 签名byte数组
         * @return 32位签名字符串
         */
        private static String hexdigest(byte[] paramArrayOfByte) {
            final char[] hexDigits = { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97,
                    98, 99, 100, 101, 102 };
            try {
                MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
                localMessageDigest.update(paramArrayOfByte);
                byte[] arrayOfByte = localMessageDigest.digest();
                char[] arrayOfChar = new char[32];
                for (int i = 0, j = 0; ; i++, j++) {
                    if (i >= 16) {
                        return new String(arrayOfChar);
                    }
                    int k = arrayOfByte[i];
                    arrayOfChar[j] = hexDigits[(0xF & k >>> 4)];
                    arrayOfChar[++j] = hexDigits[(k & 0xF)];
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        }
    
        /**
         * 清理后台进程与服务
         *
         * @param context 应用上下文对象context
         * @return 被清理的数量
         */
        public static int gc(Context context) {
            long i = getDeviceUsableMemory(context);
            int count = 0; // 清理掉的进程数
            ActivityManager am = (ActivityManager) context.getSystemService(
                    Context.ACTIVITY_SERVICE);
            // 获取正在运行的service列表
            List<RunningServiceInfo> serviceList = am.getRunningServices(100);
            if (serviceList != null) {
                for (RunningServiceInfo service : serviceList) {
                    if (service.pid == android.os.Process.myPid()) continue;
                    try {
                        android.os.Process.killProcess(service.pid);
                        count++;
                    } catch (Exception e) {
                        e.getStackTrace();
                    }
                }
            }
    
            // 获取正在运行的进程列表
            List<RunningAppProcessInfo> processList = am.getRunningAppProcesses();
            if (processList != null) {
                for (RunningAppProcessInfo process : processList) {
                    // 一般数值大于RunningAppProcessInfo.IMPORTANCE_SERVICE的进程都长时间没用或者空进程了
                    // 一般数值大于RunningAppProcessInfo.IMPORTANCE_VISIBLE的进程都是非可见进程,也就是在后台运行着
                    if (process.importance >
                            RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
                        // pkgList 得到该进程下运行的包名
                        String[] pkgList = process.pkgList;
                        for (String pkgName : pkgList) {
                            if (DEBUG) {
    
                            }
                            try {
                                am.killBackgroundProcesses(pkgName);
                                count++;
                            } catch (Exception e) { // 防止意外发生
                                e.getStackTrace();
                            }
                        }
                    }
                }
            }
            if (DEBUG) {
    
            }
            return count;
        }
    
    
        /**
         * 获取设备的可用内存大小
         *
         * @param context 应用上下文对象context
         * @return 当前内存大小
         */
        public static int getDeviceUsableMemory(Context context) {
            ActivityManager am = (ActivityManager) context.getSystemService(
                    Context.ACTIVITY_SERVICE);
            MemoryInfo mi = new MemoryInfo();
            am.getMemoryInfo(mi);
            // 返回当前系统的可用内存
            return (int) (mi.availMem / (1024 * 1024));
        }
    
    
        /**
         * 获取系统中所有的应用
         *
         * @param context 上下文
         * @return 应用信息List
         */
        public static List<PackageInfo> getAllApps(Context context) {
    
            List<PackageInfo> apps = new ArrayList<PackageInfo>();
            PackageManager pManager = context.getPackageManager();
            List<PackageInfo> paklist = pManager.getInstalledPackages(0);
            for (int i = 0; i < paklist.size(); i++) {
                PackageInfo pak = paklist.get(i);
                if ((pak.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) <=
                        0) {
                    // customs applications
                    apps.add(pak);
                }
            }
            return apps;
        }
    
    
        /**
         * 获取手机系统SDK版本
         *
         * @return 如API 17 则返回 17
         */
        public static int getSDKVersion() {
            return android.os.Build.VERSION.SDK_INT;
        }
    
    
        /**
         * 是否Dalvik模式
         *
         * @return 结果
         */
        public static boolean isDalvik() {
            return "Dalvik".equals(getCurrentRuntimeValue());
        }
    
    
        /**
         * 是否ART模式
         *
         * @return 结果
         */
        public static boolean isART() {
            String currentRuntime = getCurrentRuntimeValue();
            return "ART".equals(currentRuntime) ||
                    "ART debug build".equals(currentRuntime);
        }
    
    
        /**
         * 获取手机当前的Runtime
         *
         * @return 正常情况下可能取值Dalvik, ART, ART debug build;
         */
        public static String getCurrentRuntimeValue() {
            try {
                Class<?> systemProperties = Class.forName(
                        "android.os.SystemProperties");
                try {
                    Method get = systemProperties.getMethod("get", String.class,
                            String.class);
                    if (get == null) {
                        return "WTF?!";
                    }
                    try {
                        final String value = (String) get.invoke(systemProperties,
                                "persist.sys.dalvik.vm.lib",
                                /* Assuming default is */"Dalvik");
                        if ("libdvm.so".equals(value)) {
                            return "Dalvik";
                        }
                        else if ("libart.so".equals(value)) {
                            return "ART";
                        }
                        else if ("libartd.so".equals(value)) {
                            return "ART debug build";
                        }
    
                        return value;
                    } catch (IllegalAccessException e) {
                        return "IllegalAccessException";
                    } catch (IllegalArgumentException e) {
                        return "IllegalArgumentException";
                    } catch (InvocationTargetException e) {
                        return "InvocationTargetException";
                    }
                } catch (NoSuchMethodException e) {
                    return "SystemProperties.get(String key, String def) method is not found";
                }
            } catch (ClassNotFoundException e) {
                return "SystemProperties class is not found";
            }
        }
    
    
        private final static X500Principal DEBUG_DN = new X500Principal(
                "CN=Android Debug,O=Android,C=US");
    
    
        /**
         * 检测当前应用是否是Debug版本
         *
         * @param ctx 上下文
         * @return 是否是Debug版本
         */
        public static boolean isDebuggable(Context ctx) {
            boolean debuggable = false;
            try {
                PackageInfo pinfo = ctx.getPackageManager()
                        .getPackageInfo(ctx.getPackageName(),
                                PackageManager.GET_SIGNATURES);
                Signature signatures[] = pinfo.signatures;
                for (int i = 0; i < signatures.length; i++) {
                    CertificateFactory cf = CertificateFactory.getInstance("X.509");
                    ByteArrayInputStream stream = new ByteArrayInputStream(
                            signatures[i].toByteArray());
                    X509Certificate cert = (X509Certificate) cf.generateCertificate(
                            stream);
                    debuggable = cert.getSubjectX500Principal().equals(DEBUG_DN);
                    if (debuggable) break;
                }
            } catch (PackageManager.NameNotFoundException e) {
            } catch (CertificateException e) {
            }
            return debuggable;
        }
    
    
        /**
         * 比较版本号的大小,前者大则返回一个正数,后者大返回一个负数,相等则返回0   支持4.1.2,4.1.23.4.1.rc111这种形式
         * @param version1
         * @param version2
         * @return
         */
        public static int compareVersion(String version1, String version2) throws Exception {
            if (version1 == null || version2 == null) {
                throw new Exception("compareVersion error:illegal params.");
            }
            String[] versionArray1 = version1.split("\\.");//注意此处为正则匹配,不能用".";
            String[] versionArray2 = version2.split("\\.");
            int idx = 0;
            int minLength = Math.min(versionArray1.length, versionArray2.length);//取最小长度值
            int diff = 0;
            while (idx < minLength
                    && (diff = versionArray1[idx].length() - versionArray2[idx].length()) == 0//先比较长度
                    && (diff = versionArray1[idx].compareTo(versionArray2[idx])) == 0) {//再比较字符
                ++idx;
            }
            //如果已经分出大小,则直接返回,如果未分出大小,则再比较位数,有子版本的为大;
            diff = (diff != 0) ? diff : versionArray1.length - versionArray2.length;
            return diff;
        }
    
    }
    
    

    相关文章

      网友评论

          本文标题:Android 常用工具类之 AppUtils

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