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;
}
}
网友评论