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;
}
}