AppOpsManager 一次简单应用

Android手机有一个功能,我是刚知道没几天,也是我一直都想有得功能,那就是禁止掉某些app的权限。在安装app的时候,界面会列出App 已申请的权限,然后让用户决定是否安装。问题是我需要这个app的某些功能,这些功能我觉得不需要那么多得权限。比如我不想让这个app有读取短信通讯录权限,他用到这些权限的功能又是我不需要的。怎么办,以前我没啥办法,装呗,谁让我非要用这个app呢。现在我知道了,原来是可以禁用app的某些权限的, 从Android 4.3开始谷歌就就将权限管理功能集成系统里了,Google把他叫App Ops(Application Operations)。
我是怎么知道有这么一个功能的呢,因为我开发的一个app需要用到手机定位功能,gps+WiFi+基站都定位失败,后来才知道定位功能被禁用了。作为一个程序员就要思考怎么才能让程序知道这次定位失败是没有权限的原因还是一些其他原因呢,通过网上查找知道了AppOpsManager类,


AppOpsManager 是在是在Android 4.4版本支持的 (api 19)。获得他实例的方法是

Context.getSystemService(Context.APP_OPS_SERVICE)

APP_OPS_SERVICE 的值是 “appops”

AppOpsManager类里有一函数 int checkOp(String op, int uid, String packageName)

    public int checkOp(String op, int uid, String packageName) {
        return checkOp(strOpToOp(op), uid, packageName);
    }
    public static int strOpToOp(String op) {
        Integer val = sOpStrToOp.get(op);
        if (val == null) {
            throw new IllegalArgumentException("Unknown operation string: " + op);
        }
        return val;
    }   
功能就是快速检测某个应用是否具有某些权限,看上面的源码可知道最终调用了下面的代码

    public int checkOp(int op, int uid, String packageName) {
        try {
            int mode = mService.checkOperation(op, uid, packageName);
            if (mode == MODE_ERRORED) {
                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
            }
            return mode;
        } catch (RemoteException e) {
        }
        return MODE_IGNORED;
    }
   op 的值是 0 ~ 47,其中0代表粗略定位权限,1代表精确定位权限,24代表悬浮窗权限。
   uid 当前应用用到的uid ,可通过 Binder.getCallingUid()获得。
   packageName 应用程序的包名,通过getPackageName获得。

通过上面的知识,写一函数 用来判断 程序是否具有某些权限的函数

    private static int checkOp(Context context, int op){
        final int version = Build.VERSION.SDK_INT;
        if (version >= 19){
            Object object = context.getSystemService("appops");
            Class c = object.getClass();
            try {          
                Class[] cArg = new Class[3];
                cArg[0] = int.class;
                cArg[1] = int.class;
                cArg[2] = String.class;
                Method lMethod = c.getDeclaredMethod("checkOp", cArg);
                return (Integer) lMethod.invoke(object, op, Binder.getCallingUid(), context.getPackageName());
            } catch(NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }        
        }
        return -1;
    }

调用上面的函数,返回 0 就代表有权限,1代表没有权限,-1函数出错啦




你可能感兴趣的:(AppOpsManager 一次简单应用)