关于定位权限的问题

news/2024/10/17 9:10:43/

对于应用的开发,往往会通过如下方式判断是否有开启定位权限

            int hasCallPhonePermission = MartinApplication.getInstance().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION);
            int hasCallPhonePermission1 = MartinApplication.getInstance().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION);

            if (hasCallPhonePermission != PackageManager.PERMISSION_GRANTED) {
                return false;
            }

其中ACCESS_COARSE_LOCATION表示大致定位,即通过网络定位,ACCESS_FINE_LOCATION表示精确定位,是通过GPS和网络来定位的。


这里有个问题,关于android定位等运行时权限问题,android是从版本5.1才开始支持的,即SDK版本,也就是 Build.VERSION_CODES.LOLLIPOP_MR1

而对于低版本的,则不支持运行时权限。

对于开发的应用设置为minSdkVersion版本低于22,那么在系统应用管理界面设置关闭定位权限的时候,系统会提示“该应用是针对低版本设计的,关闭权限可能导致问题”,如果选择关闭,那么其实系统并不会真的关闭该权限(代码位置packages/apps/PackageInstaller/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java : revokeRuntimePermissions()),而是会检查该项权限是否有AppOp权限,如果有,则会关闭AppOp权限(测试android7.0,关闭定位的AppOp其实并未起作用),然后也会给相应的权限添加flag : FLAG_PERMISSION_REVOKE_ON_UPGRADE,然后在应用升级到合适的版本之后再把相应的权限职位deny。


综上可知,如果想通过开始的那种方法获取应用权限开启状态的话,在低版本的应用中是无法成功的,结果都是granted=true。


附:

查看应用当前权限状态:

dumpsys package <packageName> //如下,因为是低版本应用,所以runtime permissions为空,定位权限虽然关闭,但是granted=true,只是添加了flags=REVOKE_ON_UPGRADE

install permissions:

      android.permission.WRITE_SETTINGS: granted=true

      android.permission.ACCESS_FINE_LOCATION: granted=true, flags=[ REVOKE_ON_UPGRADE ]

      android.permission.SYSTEM_ALERT_WINDOW: granted=true

      android.permission.CHANGE_NETWORK_STATE: granted=true

      android.permission.RECEIVE_BOOT_COMPLETED: granted=true

      android.permission.RECEIVE_SMS: granted=true

      android.permission.BLUETOOTH: granted=true

      android.permission.GET_TASKS: granted=true

      android.permission.INTERNET: granted=true

      android.permission.READ_EXTERNAL_STORAGE: granted=true

      android.permission.ACCESS_COARSE_LOCATION: granted=true, flags=[ REVOKE_ON_UPGRADE ]

      android.permission.READ_PHONE_STATE: granted=true

      android.permission.ACCESS_LOCATION_EXTRA_COMMANDS: granted=true

      android.permission.SEND_SMS: granted=true

      android.permission.CALL_PHONE: granted=true

      com.xxxx.zzz.permission.MESSAGE: granted=true

      android.permission.FLASHLIGHT: granted=true

      android.permission.ACCESS_NETWORK_STATE: granted=true

      android.permission.CAMERA: granted=true

      com.xxxx.zzz.permission.MIPUSH_RECEIVE: granted=true

      android.permission.WRITE_EXTERNAL_STORAGE: granted=true

      android.permission.VIBRATE: granted=true

      android.permission.ACCESS_WIFI_STATE: granted=true

      com.xxxx.zzz.permission.C2D_MESSAGE: granted=true

    User 0: ceDataInode=21307 installed=true hidden=false suspended=false stopped=false notLaunched=false enabled=0

      gids=[3002, 3003]

      runtime permissions:


获取AppOp方法:

appops get <pkgName> //虽然定位已经关闭,但是结果依然是allow,原因未知

COARSE_LOCATION: allow; time=+7s911ms ago

FINE_LOCATION: allow; time=+7s909ms ago

WRITE_SMS: ignore; rejectTime=+56s367ms ago

WRITE_SETTINGS: default; rejectTime=+56s901ms ago

OP_READ_PHONE_STATE: allow; time=+15s939ms ago

READ_EXTERNAL_STORAGE: allow; time=+15s930ms ago

WRITE_EXTERNAL_STORAGE: allow; time=+15s930ms ago

RUN_IN_BACKGROUND: allow; time=+6s104ms ago


而使用另外一个方法则能看到appops的正常状态(经测试android原生设备可以,测试Oppo、meizu手机并无此效果,目测他们实现了自己的针对低版本应用的权限管理机制)

dumpsys appops

  Uid u0a125:

      COARSE_LOCATION: mode=1 //表示当前appops权限为reject

      CALL_PHONE: mode=1

      OP_READ_PHONE_STATE: mode=1

    Package com.xxxx.zzzz:

      COARSE_LOCATION: mode=0; time=+13h28m1s90ms ago; rejectTime=+3m27s329ms ago //上次拒绝时间?

      FINE_LOCATION: mode=0; time=+13h28m1s86ms ago; rejectTime=+3m27s329ms ago

      WIFI_SCAN: mode=0; rejectTime=+12h56m51s504ms ago

      POST_NOTIFICATION: mode=0; time=+12h56m51s323ms ago

      CALL_PHONE: mode=0; rejectTime=+13h25m59s363ms ago

      WRITE_SMS: mode=1; rejectTime=+13h12m35s578ms ago


故而,可以通过如下反射方式获取该状态下的权限状态(注:获取appops的方法是隐藏方法,所以使用该方法有一定风险)

public static final int OP_COARSE_LOCATION = 0;
/** @hide Access to fine location information. */
public static final int OP_FINE_LOCATION = 1;

/**
 * 是否禁用某项操作
 */
@TargetApi(Build.VERSION_CODES.KITKAT)
public static boolean isAllowed(Context context, int op) {Log.d(TAG, "api level: " + Build.VERSION.SDK_INT);
    if (Build.VERSION.SDK_INT < 19) {return true;
    }Log.d(TAG, "op is " + op);
    String packageName = context.getApplicationContext().getPackageName();
    AppOpsManager aom = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
    Class<?>[] types = new Class[]{int.class, int.class, String.class};
    Object[] args = new Object[]{op, Binder.getCallingUid(), packageName};
    try {Method method = aom.getClass().getDeclaredMethod("checkOpNoThrow", types);
        Object mode = method.invoke(aom, args);
        Log.d(TAG, "invoke checkOpNoThrow: " + mode);
        if ((mode instanceof Integer) && ((Integer) mode == AppOpsManager.MODE_ALLOWED)) {Log.d(TAG, "allowed");
            return true;
        }} catch (Exception e) {Log.e(TAG, "invoke error: " + e);
        e.printStackTrace();
    }return false;
}



http://www.ppmy.cn/news/394811.html

相关文章

ESP8266开发 --- 重新烧录固件DownLoadTool参数解释

步骤一&#xff1a; 提示&#xff1a;待烧录文件中&#xff0c;一般只烧录1、2两个文件即可&#xff0c;3、4、5在出厂时已烧录过&#xff0c;不用每次调试代码都烧录。 但在以下两种情况下要重新烧录&#xff1a; 外部Flash中的数据被意外破坏&#xff0c;如野指针...批量生…

设计模式之 Factory Mode 工厂模式:Swift 实现

Factory Mode 工厂模式 Provide the method for creating an instance in the superclass, and allow the subclass to choose the type of the instance. 在父类中提供创建对象的方法&#xff0c;允许子类决定实例化对象的类型。 具备的部分&#xff1a;生产者协议、产品协…

Setup Factory 点击uninstall.exe Invalid start mode : archive filename

搜了很多资料&#xff0c;琢磨半天&#xff0c;找到一个有效方法&#xff0c;记录下 点击uninstall.exe不生效&#xff0c;主要是因为没带参数 方法&#xff1a;生成一个快捷方式&#xff0c;添加命令 Shell.CreateShortcut("%AppFolder%", "卸载 NetManage.e…

Review and start again——First Period JAVA web Program hotelmanagement:6.some about JAVA factory mode

Today I’d like to discuss something about the JAVA factory mode. JAVA factory mode is the mode which can take the place of the new(**) to instantiate an object. The brilliant interpretation of it I’v ever seen is: https://blog.csdn.net/RivenDong/articl…

Setup Factory 提示 Invalid start mode : archive filename 的解决办法

第一步&#xff1a; 打开在安装之后 创建一个卸载的快捷方式 代码如下&#xff1a; Shell.CreateShortcut("%AppFolder%", "卸载 NetManage.exe", "%AppFolder%\\uninstall.exe", "/U:.\\Uninstall\\uninstall.xml", "%AppFol…

[Camera Drv]Factory mode下camera图像rotate了180度 - MTK物联网在线解答 - 技术论坛

[Camera Drv]Factory mode下 camera图像rotate了180度 在projectconfig.mk中设置了MTK_LCM_PHYSICAL_ROTATION180,则Factorymode下camera旋转180度 最佳答案 FDD2打patch&#xff0c;patchid&#xff1a;ALPS253222, ALPS00259131 GB2打patch&#xff0c;patchid&#xff1a;AL…

telnet连接失败的常见错误

telnet提示“在端口23&#xff1a;连接失败”&#xff0c;说明没有开启telnet服务。 解决方法如下 1、在运用telnet命令时经常显示不是内部或外部命令&#xff0c;或无法打开到主机的连接&#xff0c;在端口23&#xff1a;连接失败&#xff0c;如下图。 2、点击左下角控制面…

Setup Factory 卸载时出现Invalid Start mode :archive filename 无法卸载问题

最近要打包程序在网上找啦几个打包工具最后感觉SetupFactory用着舒服,然后愉快的下载使用,前面都很满意。但是最后安装之后卸载时出现了问题。 执行安装目标下的uninstall.exe后会弹出如下错误 在网上找啦一圈没有发现解决方案。 最后发现生成在开始菜单中卸载快捷方式可以正常…