android 应用启动监测/拦截,白名单应用

需求:做一个系统服务或者应用;可以根据后台配置的黑白名单,禁用应用启动。如果是黑名单应用,则点击了,也无法启动。

这里不做后台拉取黑名单的动作。只做 如何检测其他应用启动。检测到了,就可以禁止启动了。
具体如下。

这里作为非系统app来进行说明,系统app要简单一些,但差别不大。
知识点及介绍参考文章如下:

  1. IActivityController
  2. 调用系统hide函数
  3. 反射
  4. 权限
  5. 签名及gradle中如何加载签名,及如何生成相关签名文件

IActivityController

使用IActivityController监听所有app启动的状态。
如下:

 public class MyActivityController extends IActivityController.Stub {
        public boolean activityStarting(Intent intent, String pkg) {
            Log.d(TAG, "activityStarting: " + pkg + ", intent= " + intent);
            //retrun false;//false 则不会启动,直接返回。
            return true;
        }

        public boolean activityResuming(String pkg) {
            Log.d(TAG, "activityResuming: " + pkg);
            return true;
        }

        public int appEarlyNotResponding(String processName, int pid,
                                         String annotation) {
            return 0;
        }

        public boolean appCrashed(String processName, int pid, String shortMsg,
                                  String longMsg, long timeMillis, String stackTrace) {
            return false;
        }

        public int appNotResponding(String processName, int pid,
                                    String processStats) {
            return 0;
        }

        public int systemNotResponding(String msg) {
            return 1;
        }
    }

但是正常情况下,是无法使用的,这个是系统级别的。所以需要权限、反射、系统签名才能使用。
检测其他app启动情况就如上面函数。
在activityStarting回调中进行处理,如果是黑名单则return false,则不会启动,retrun true,正常启动。
如何使用系统级别的函数呢,在2中介绍。

调用系统hide函数及反射

1中是监听,则需要在某个地方,把这个监听设置一下。
伪代码:ActivityManagerNative.setActivityController(new MyActivityController())
区别5.1和7.1,其他版本setActivityController里参数是否有差异不确定,如果需要兼容,则根据函数的参数进行一下处理即可。反射参考推荐文章。
反射获取相关类及方法。实际代码如下:

    private void setActivityController() {
        Log.d(TAG, "setActivityController: ...........");
        try {
            Class<?> cActivityManagerNative = Class
                    .forName("android.app.ActivityManagerNative");
            Method mGetDefault = cActivityManagerNative.getMethod("getDefault",
                    null);
            Object oActivityManagerNative = mGetDefault.invoke(null, null);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
                Method mSetActivityController = cActivityManagerNative.getMethod(
                        "setActivityController",
                        Class.forName("android.app.IActivityController"), Boolean.TYPE);
                mSetActivityController.invoke(oActivityManagerNative,
                        new ActivityController(), true);
            } else {
                Method mSetActivityController = cActivityManagerNative.getMethod(
                        "setActivityController",
                        Class.forName("android.app.IActivityController"));
                mSetActivityController.invoke(oActivityManagerNative,
                        new ActivityController());
            }

            Log.d(TAG, "setActivityController: ....................end");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

直接这么写肯定会报错的,所以需要配置一下。
这里需要个源码中间产物:classes.jar。在源码目录:图中绿色部分。android 应用启动监测/拦截,白名单应用_第1张图片
可以简单参考下2中给出的参考超链接。
通过classes.jar既可以在编译的时候不报错。具体原理参考推荐参考文章。
在这里插入图片描述
AndroidStudio中配置:
将classes.jar放到相应目录,并在gradle中配置一下。如下图:
android 应用启动监测/拦截,白名单应用_第2张图片
android 应用启动监测/拦截,白名单应用_第3张图片

权限

使用setActivityController需要系统权限:SET_ACTIVITY_WATCHER
在menifest中配置一下。这个权限是系统级别的,所以三方app配置后也无法生效,需要增加android:sharedUserId="android.uid.system",而这个shareduid需要是系统级别app,否则无法安装,所谓系统级别,就是有系统的签名。
android 应用启动监测/拦截,白名单应用_第4张图片

签名及gradle中如何加载签名,及如何生成相关签名文件

参考文章即可,一般如果给其他厂商用,厂商会要求你把apk发过去,他们进行apk签名,然后可以安装到设备上。签名文件一般不会给你。
如果是自己公司开发,有自己的系统,则可以拿到签名文件自己签名,或者生成as所需要的签名文件,在as打包时自动签名。
具体签名及生成签名文件的方法参考推荐文章。
android 应用启动监测/拦截,白名单应用_第5张图片

在as真配置一下生成好的签名文件:
android 应用启动监测/拦截,白名单应用_第6张图片
这样便可以安装到设备上,进行调试了。
否则app因没签名,但使用android:sharedUserId="android.uid.system"导致无法安装。

相关demo放到了gtihub上。其中签名文件被我删除了,一个是放上去,一般也用不了,需要根据具体设备而定。
无论怎样,都需要有签名或者源码的环境才可行。

你可能感兴趣的:(android)