|
|
@@ -0,0 +1,151 @@
|
|
|
+package net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils;
|
|
|
+
|
|
|
+import android.app.ActivityManager;
|
|
|
+import android.app.KeyguardManager;
|
|
|
+import android.content.Context;
|
|
|
+import android.content.Intent;
|
|
|
+import android.content.pm.ApplicationInfo;
|
|
|
+import android.content.pm.PackageManager;
|
|
|
+import android.content.pm.ResolveInfo;
|
|
|
+
|
|
|
+import java.lang.reflect.Field;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Description: Activity反劫持检测工具
|
|
|
+ * author: zs
|
|
|
+ * Date: 2018/7/8 16:31
|
|
|
+ */
|
|
|
+public class AntiHijackingUtil {
|
|
|
+ public static final String TAG = "AntiHijackingUtil";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检测当前Activity是否安全
|
|
|
+ */
|
|
|
+ public static boolean checkActivity(Context context) {
|
|
|
+ PackageManager pm = context.getPackageManager();
|
|
|
+ // 查询所有已经安装的应用程序
|
|
|
+ List<ApplicationInfo> listAppcations =
|
|
|
+ pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
|
|
|
+ Collections.sort(listAppcations, new ApplicationInfo.DisplayNameComparator(pm));// 排序
|
|
|
+
|
|
|
+ List<String> safePackages = new ArrayList<>();
|
|
|
+ for (ApplicationInfo app : listAppcations) {// 这个排序必须有.
|
|
|
+ if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
|
|
|
+ safePackages.add(app.packageName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 得到所有的系统程序包名放进白名单里面.
|
|
|
+ ActivityManager activityManager =
|
|
|
+ (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
|
|
+ String runningActivityPackageName;
|
|
|
+ int sdkVersion;
|
|
|
+ try {
|
|
|
+ sdkVersion = Integer.valueOf(android.os.Build.VERSION.SDK);
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ sdkVersion = 0;
|
|
|
+ }
|
|
|
+ if (sdkVersion >= 21) {// 获取系统api版本号,如果是5x系统就用这个方法获取当前运行的包名
|
|
|
+ runningActivityPackageName = getCurrentPkgName(context);
|
|
|
+ } else {
|
|
|
+ runningActivityPackageName =
|
|
|
+ activityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
|
|
|
+ }
|
|
|
+ // 如果是4x及以下,用这个方法.
|
|
|
+ if (runningActivityPackageName != null) {
|
|
|
+ // 有些情况下在5x的手机中可能获取不到当前运行的包名,所以要非空判断。
|
|
|
+ if (runningActivityPackageName.equals(context.getPackageName())) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ // 白名单比对
|
|
|
+ for (String safePack : safePackages) {
|
|
|
+ if (safePack.equals(runningActivityPackageName)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String getCurrentPkgName(Context context) {
|
|
|
+ // 5x系统以后利用反射获取当前栈顶activity的包名.
|
|
|
+ ActivityManager.RunningAppProcessInfo currentInfo = null;
|
|
|
+ Field field = null;
|
|
|
+ int START_TASK_TO_FRONT = 2;
|
|
|
+ String pkgName = null;
|
|
|
+ try {
|
|
|
+ // 通过反射获取进程状态字段.
|
|
|
+ field = ActivityManager.RunningAppProcessInfo.class.getDeclaredField("processState");
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
|
|
+ List appList = am.getRunningAppProcesses();
|
|
|
+ ActivityManager.RunningAppProcessInfo app;
|
|
|
+ for (int i = 0; i < appList.size(); i++) {
|
|
|
+ //ActivityManager.RunningAppProcessInfo app : appList
|
|
|
+ app = (ActivityManager.RunningAppProcessInfo) appList.get(i);
|
|
|
+ //表示前台运行进程.
|
|
|
+ if (app.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
|
|
|
+ Integer state = null;
|
|
|
+ try {
|
|
|
+ state = field.getInt(app);// 反射调用字段值的方法,获取该进程的状态.
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ // 根据这个判断条件从前台中获取当前切换的进程对象
|
|
|
+ if (state != null && state == START_TASK_TO_FRONT) {
|
|
|
+ currentInfo = app;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (currentInfo != null) {
|
|
|
+ pkgName = currentInfo.processName;
|
|
|
+ }
|
|
|
+ return pkgName;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断当前是否在桌面
|
|
|
+ *
|
|
|
+ * @param context 上下文
|
|
|
+ */
|
|
|
+ public static boolean isHome(Context context) {
|
|
|
+ ActivityManager mActivityManager =
|
|
|
+ (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
|
|
+ List<ActivityManager.RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);
|
|
|
+ return getHomes(context).contains(rti.get(0).topActivity.getPackageName());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获得属于桌面的应用的应用包名称
|
|
|
+ *
|
|
|
+ * @return 返回包含所有包名的字符串列表
|
|
|
+ */
|
|
|
+ private static List<String> getHomes(Context context) {
|
|
|
+ List<String> names = new ArrayList<String>();
|
|
|
+ PackageManager packageManager = context.getPackageManager();
|
|
|
+ Intent intent = new Intent(Intent.ACTION_MAIN);
|
|
|
+ intent.addCategory(Intent.CATEGORY_HOME);
|
|
|
+ List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intent,
|
|
|
+ PackageManager.MATCH_DEFAULT_ONLY);
|
|
|
+ for (ResolveInfo ri : resolveInfo) {
|
|
|
+ names.add(ri.activityInfo.packageName);
|
|
|
+ }
|
|
|
+ return names;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断当前是否在锁屏再解锁状态
|
|
|
+ *
|
|
|
+ * @param context 上下文
|
|
|
+ */
|
|
|
+ public static boolean isReflectScreen(Context context) {
|
|
|
+ KeyguardManager mKeyguardManager =
|
|
|
+ (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
|
|
|
+ return mKeyguardManager.inKeyguardRestrictedInputMode();
|
|
|
+ }
|
|
|
+}
|