package com.arialyy.frame.util; import android.annotation.TargetApi; import android.app.Activity; import android.app.ActivityManager; 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.ResolveInfo; import android.content.res.Resources; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.StatFs; import android.provider.Settings; import android.support.annotation.NonNull; import android.telephony.TelephonyManager; import android.util.DisplayMetrics; import android.view.WindowManager; import com.arialyy.frame.util.show.FL; import com.arialyy.frame.util.show.L; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; /** * android系统工具类 */ public class AndroidUtils { private static final String TAG = "AndroidUtils"; private AndroidUtils() { } /** * 检查权限 * * @param permission android.permission.WRITE_EXTERNAL_STORAGE * @return manifest 已经定义了则返回true */ public static boolean checkPermission(@NonNull Context context, @NonNull String permission) { return context.checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_GRANTED; } /** * 申请root权限 * * @return 应用程序是/否获取Root权限 */ public static boolean getRootPermission(String pkgCodePath) { Process process = null; DataOutputStream os = null; try { String cmd = "chmod 777 " + pkgCodePath; process = Runtime.getRuntime().exec("su"); //切换到root帐号 os = new DataOutputStream(process.getOutputStream()); os.writeBytes(cmd + "\n"); os.writeBytes("exit\n"); os.flush(); return process.waitFor() == 0; } catch (Exception e) { return false; } finally { try { if (os != null) { os.close(); } if (process != null) { process.destroy(); } } catch (IOException e) { e.printStackTrace(); } } } /** * 获取指定包名的包信息 */ public static PackageInfo getAppInfo(Context context, String packageName) { try { return context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_ACTIVITIES); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return null; } } /** * 获取未安装软件包的包名 */ public static String getApkPackageName(Context context, String apkPath) { PackageManager pm = context.getPackageManager(); PackageInfo info = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES); if (info != null) { ApplicationInfo appInfo = info.applicationInfo; appInfo.sourceDir = apkPath; appInfo.publicSourceDir = apkPath; return appInfo.packageName; } return ""; } /** * 判断是否安装 */ public static boolean apkIsInstall(Context context, String apkPath) { PackageManager pm = context.getPackageManager(); PackageInfo info = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES); if (info != null) { ApplicationInfo appInfo = info.applicationInfo; appInfo.sourceDir = apkPath; appInfo.publicSourceDir = apkPath; try { pm.getPackageInfo(appInfo.packageName, PackageManager.GET_UNINSTALLED_PACKAGES); return true; } catch (PackageManager.NameNotFoundException localNameNotFoundException) { return false; } } return false; } /** * 判断服务是否后台运行 * * @param context Context * @param clazz * @return true 在运行 false 不在运行 */ public static boolean isServiceRun(Context context, Class<?> clazz) { boolean isRun = false; ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningServiceInfo> serviceList = activityManager.getRunningServices(Integer.MAX_VALUE); int size = serviceList.size(); for (int i = 0; i < size; i++) { if (serviceList.get(i).service.getClassName().equals(clazz.getName())) { isRun = true; break; } } return isRun; } /** * 启动另外一个App */ public static void startOtherApp(Context context, String packageName) { PackageManager pm = context.getPackageManager(); Intent launcherIntent = pm.getLaunchIntentForPackage(packageName); context.startActivity(launcherIntent); } /** * 判断手机是否拥有Root权限。 * * @return 有root权限返回true,否则返回false。 */ public static boolean isRoot() { String binPath = "/system/bin/su"; String xBinPath = "/system/xbin/su"; return new File(binPath).exists() && isExecutable(binPath) || new File(xBinPath).exists() && isExecutable(xBinPath); } private static boolean isExecutable(String filePath) { Process p = null; try { p = Runtime.getRuntime().exec("ls -l " + filePath); // 获取返回内容 BufferedReader in = new BufferedReader(new InputStreamReader( p.getInputStream())); String str = in.readLine(); L.i(TAG, str); if (str != null && str.length() >= 4) { char flag = str.charAt(3); if (flag == 's' || flag == 'x') return true; } } catch (IOException e) { e.printStackTrace(); } finally { if (p != null) { p.destroy(); } } return false; } /** * 静默卸载 */ public static boolean uninstallInBackground(String packageName) { String command = "pm uninstall -k " + packageName + "\n"; ShellUtils.CommandResult result = ShellUtils.execCommand(command, true); String errorMsg = result.errorMsg; L.d(TAG, "error msg = " + result.errorMsg); L.d(TAG, "success msg = " + result.successMsg); int res = result.result; return res == 0 && !errorMsg.contains("Failure"); } /** * 静默安装APk * 执行具体的静默安装逻辑,需要手机ROOT。 * * @param apkPath 要安装的apk文件的路径 * @return 安装成功返回true,安装失败返回false。 */ public static boolean installInBackground(String apkPath) { String command = "pm install -r " + apkPath + "\n"; ShellUtils.CommandResult result = ShellUtils.execCommand(command, true); String errorMsg = result.errorMsg; L.d(TAG, "error msg = " + result.errorMsg); L.d(TAG, "success msg = " + result.successMsg); int res = result.result; return res == 0 && !errorMsg.contains("Failure"); } /** * 获取状态栏高度 */ public static int getStatusBarHeight(Context context) { int result = 0; int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = context.getResources().getDimensionPixelSize(resourceId); } return result; } /** * 获取导航栏高度 */ public static int getNavigationBarHeight(Context context) { Resources resources = context.getResources(); int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android"); if (resourceId > 0) { return resources.getDimensionPixelSize(resourceId); } return 0; } /** * 获取当前窗口的高度, 该高度是不包含导航栏和状态栏的 */ public static int getWindowHeight(Activity activity) { return activity.getWindow().getWindowManager().getDefaultDisplay().getHeight(); } /** * 获取当前窗口的宽度 * * @param activity * @return */ public static int getWindowWidth(Activity activity) { return activity.getWindow().getWindowManager().getDefaultDisplay().getWidth(); } /** * 获取屏幕参数,这个获取到的高是包含导航栏和状态栏的 * * @param context * @return */ public static int[] getScreenParams(Context context) { WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); return new int[]{wm.getDefaultDisplay().getWidth(), wm.getDefaultDisplay().getHeight()}; } /** * 检查手机是否安装了指定的APK * * @param packageName 该APK的包名 * @return */ public static boolean checkApkExists(Context context, String packageName) { List<PackageInfo> packageInfos = getAllApps(context); for (PackageInfo pi : packageInfos) { if (pi.packageName.equals(packageName)) { return true; } } return false; } /** * 查询手机内所有应用 * * @param context * @return */ 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); apps.add(pak); } return apps; } /** * 查询手机内非系统应用 * * @param context * @return */ public static List<PackageInfo> getAllNoSystemApps(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; } /** * 获取目录 */ public static String getSourcePath(Context context, String packageName) { ApplicationInfo appInfo = null; try { appInfo = context.getPackageManager().getApplicationInfo(packageName, 0); return appInfo.sourceDir; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return null; } /** * 获取包名 */ public static String getPackageName(Context context) { return getPackageInfo(context).packageName; } /** * 获取应用名 */ public static String getAppName(Context context) { try { return context.getString(context.getApplicationInfo().labelRes); } catch (Resources.NotFoundException e) { FL.e(TAG, FL.getExceptionString(e)); return ""; } } /** * 获取设备的唯一ID * * @param context * @return */ public static String getAndroidId(Context context) { return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); } /** * 返回版本名称 * * @param context * @return */ public static String getVersionName(Context context) { return getPackageInfo(context).versionName; } /** * 返回版本号 * * @param context * @return */ public static int getVersionCode(Context context) { return getPackageInfo(context).versionCode; } /** * 打开一个隐藏了图标的APP * * @param context */ public static void openAppWithAction(Context context, String packageName, String activity) { ComponentName componentName = new ComponentName(packageName, activity); try { Intent intent = new Intent(); intent.setComponent(componentName); context.startActivity(intent); } catch (Exception e) { FL.e(TAG, "没有找到应用程序:packageName:" + packageName + " activity:" + activity); } } /** * 应用是否被安装 * * @param context * @param packageName * @return */ public static boolean isInstall(Context context, String packageName) { PackageInfo packageInfo = null; try { packageInfo = context.getPackageManager().getPackageInfo(packageName, 0); } catch (PackageManager.NameNotFoundException e) { // e.printStackTrace(); } return packageInfo != null; } /** * 安装APP * * @param file */ public static void install(Context context, File file) { FL.e(TAG, "install Apk:" + file.getName()); context.startActivity(getInstallIntent(file)); } /** * 卸载APk * * @param context * @param packageName 包名 */ public static void uninstall(Context context, String packageName) { Uri packageURI = Uri.parse("package:" + packageName); Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI); uninstallIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(uninstallIntent); } /** * 获取安装应用的Intent * * @param file * @return */ public static Intent getInstallIntent(File file) { Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); return intent; } /** * 拷贝Assets中的文件到指定目录 * * @param context * @param fileName * @param path * @return */ public static boolean copyFileFromAssets(Context context, String fileName, String path) { boolean copyIsFinish = false; try { InputStream is = context.getAssets().open(fileName); File file = FileUtil.createFile(path); FileOutputStream fos = new FileOutputStream(file); byte[] temp = new byte[1024]; int i = 0; while ((i = is.read(temp)) > 0) { fos.write(temp, 0, i); } fos.close(); is.close(); copyIsFinish = true; } catch (IOException e) { e.printStackTrace(); } return copyIsFinish; } /** * 获取版本信息 */ public static PackageInfo getPackageInfo(Context context) { PackageInfo pkg = null; if (context == null) { return null; } try { pkg = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return pkg; } /** * 获取设备的显示属性 * * @param context * @return */ public static DisplayMetrics getDisplayMetrics(Context context) { return context.getResources().getDisplayMetrics(); } /** * 获取电话号码 * * @param context * @return */ public static String getLocalPhoneNumber(Context context) { String line1Number = getTelephonyManager(context).getLine1Number(); return line1Number == null ? "" : line1Number; } /** * 获取设备型号(Nexus5) * * @return */ public static String getDeviceModel() { return Build.MODEL; } /** * 获取电话通讯管理(可以通过这个对象获取手机号码等) */ public static TelephonyManager getTelephonyManager(Context context) { return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); } /** * 获取版本号 */ public static String getSystemVersion() { // 获取android版本号 return Build.VERSION.RELEASE; } /** * 返回ApplicationInfo(可以通过这个读取meta-data等等) */ public static ApplicationInfo getApplicationInfo(Context context) { if (context == null) { return null; } ApplicationInfo applicationInfo = null; try { applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return applicationInfo; } /** * 获取MetaData的Bundle */ public static Bundle getMetaData(Context context) { ApplicationInfo applicationInfo = getApplicationInfo(context); if (applicationInfo == null) { return new Bundle(); } return applicationInfo.metaData; } /** * 应用是否启动 */ public static boolean appIsRunning(Context context) { boolean isAppRunning = false; ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> list = am.getRunningTasks(100); String packageName = getPackageInfo(context).packageName; for (ActivityManager.RunningTaskInfo info : list) { if (info.topActivity.getPackageName().equals(packageName) && info.baseActivity.getPackageName().equals(packageName)) { isAppRunning = true; //find it, break break; } } return isAppRunning; } /** * 检查系统是否有这个Intent,在启动Intent的时候需要检查,因为启动一个没有的Intent程序会Crash */ public static boolean isIntentSafe(Context context, Intent intent) { PackageManager packageManager = context.getPackageManager(); List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0); return activities.size() > 0; } /** * 获取当前包的系统缓存目录 * "/Android/data/" + context.getPackageName() + "/cache" */ public static String getDiskCacheDir(Context context) { // Check if media is mounted or storage is built-in, if so, try and use external cache dir // otherwise use internal cache dir File cacheDirPath = getExternalCacheDir(context); if (cacheDirPath == null) { cacheDirPath = context.getCacheDir(); } return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !isExternalStorageRemovable() ? cacheDirPath.getPath() : context.getCacheDir().getPath(); } /** * 获取当前包的外置路径 * "/Android/data/" + context.getPackageName() */ public static String getDiskPackage(Context context) { return new File(getDiskCacheDir(context)).getParent(); } /** * Check if external storage is built-in or removable. * * @return True if external storage is removable (like an SD card), false * otherwise. */ @TargetApi(Build.VERSION_CODES.GINGERBREAD) public static boolean isExternalStorageRemovable() { return !AndroidVersionUtil.hasGingerbread() || Environment.isExternalStorageRemovable(); } /** * Get the external app cache directory. * * @param context The context to use * @return The external cache dir */ @TargetApi(Build.VERSION_CODES.FROYO) public static File getExternalCacheDir(Context context) { if (AndroidVersionUtil.hasFroyo()) { File cacheDir; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) { // /sdcard/Android/data/<application package>/cache if (context == null) { NullPointerException ex = new NullPointerException("context == null"); FL.e(TAG, FL.getExceptionString(ex)); throw ex; } cacheDir = context.getExternalCacheDir(); } else { // /data/data/<application package>/cache cacheDir = context.getCacheDir(); } return cacheDir; } // Before Froyo we need to construct the external cache dir ourselves final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/"; return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir); } /** * Check how much usable space is available at a given path. * * @param path The path to check * @return The space available in bytes */ @TargetApi(Build.VERSION_CODES.GINGERBREAD) public static long getUsableSpace(File path) { if (AndroidVersionUtil.hasGingerbread()) { return path.getUsableSpace(); } final StatFs stats = new StatFs(path.getPath()); return (long) stats.getBlockSize() * (long) stats.getAvailableBlocks(); } }