美文网首页Android知识Android技术知识Android开发
小米手机6.0系统以上WRITE_SETTINGS和SYSTEM

小米手机6.0系统以上WRITE_SETTINGS和SYSTEM

作者: NamelessCoder | 来源:发表于2018-04-09 15:57 被阅读0次

    重点关注AppOpsManager这个类。要想知道这个类是干嘛的,直接去谷歌官方开发者文档中去了解。
    在AppOpsManager这个类中,可以看到


    Permissions.png

    悬浮窗和修改系统设置的权限码是24和25。并且这个类的变量,方法都是隐藏的。
    接下来,我们需要调用checkOp方法来返回真正的权限回调结果。

       /**
         * Do a quick check for whether an application might be able to perform an operation.
         * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
         * or {@link #startOp(int, int, String)} for your actual security checks, which also
         * ensure that the given uid and package name are consistent.  This function can just be
         * used for a quick check to see if an operation has been disabled for the application,
         * as an early reject of some work.  This does not modify the time stamp or other data
         * about the operation.
         * @param op The operation to check.  One of the OP_* constants.
         * @param uid The user id of the application attempting to perform the operation.
         * @param packageName The name of the application attempting to perform the operation.
         * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
         * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
         * causing the app to crash).
         * @throws SecurityException If the app has been configured to crash on this op.
         * @hide
         */
        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) {
                throw e.rethrowFromSystemServer();
            }
        }
    

    由于这个方法是隐藏的,所以需要用反射的方法来调用。也可以用这个库来进行调用 https://github.com/anggrayudi/android-hidden-api
    这个库只要直接将原本的SDK替换成这个库的SDK就能够不用通过反射来调用隐藏方法。
    反射调用checkOp的步骤:

     private static boolean isPermissionGranted(String permissionCode) {
            try {
                Object object = getSystemService(Context.APP_OPS_SERVICE);
                if (object == null) {
                    return false;
                }
                Class localClass = object.getClass();
                Class[] arrayOfClass = new Class[3];
                arrayOfClass[0] = Integer.TYPE;
                arrayOfClass[1] = Integer.TYPE;
                arrayOfClass[2] = String.class;
                Method method = localClass.getMethod("checkOp", arrayOfClass);
    
                if (method == null) {
                    return false;
                }
                Object[] arrayOfObject = new Object[3];
                arrayOfObject[0] = Integer.valueOf(permissionCode);
                arrayOfObject[1] = Integer.valueOf(Binder.getCallingUid());
                arrayOfObject[2] = getPackageName();
                int m = ((Integer) method.invoke(object, arrayOfObject)).intValue();
                return m == AppOpsManager.MODE_ALLOWED;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return false;
        }
    

    然后将悬浮窗和修改系统设置的权限码传进去就好。
    最后返回的结果既是真正的权限回调的结果。

    相关文章

      网友评论

        本文标题:小米手机6.0系统以上WRITE_SETTINGS和SYSTEM

        本文链接:https://www.haomeiwen.com/subject/ztyihftx.html