[43→100]Android M上的权限获取问题

问题描述

高德地图,在我的小米4(Android 6.0)上出现bug,日志如下:

06-07 17:58:52.761 31095-32257/com.freetek.deepsea W/System.err: java.lang.SecurityException: getCellLocation: Neither user 10549 nor current process has android.permission.ACCESS_COARSE_LOCATION.
06-07 17:58:52.762 31095-32257/com.freetek.deepsea W/System.err:     at android.os.Parcel.readException(Parcel.java:1620)
06-07 17:58:52.763 31095-32257/com.freetek.deepsea W/System.err:     at android.os.Parcel.readException(Parcel.java:1573)
06-07 17:58:52.763 31095-32257/com.freetek.deepsea W/System.err:     at com.android.internal.telephony.ITelephony$Stub$Proxy.getCellLocation(ITelephony.java:2428)
06-07 17:58:52.763 31095-32257/com.freetek.deepsea W/System.err:     at android.telephony.TelephonyManager.getCellLocation(TelephonyManager.java:831)
06-07 17:58:52.763 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.ce.m(CgiManager.java)
06-07 17:58:52.763 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.ce.l(CgiManager.java)
06-07 17:58:52.763 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.ce.f(CgiManager.java)
06-07 17:58:52.763 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.bv.G(APS.java)
06-07 17:58:52.763 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.bv.a(APS.java)
06-07 17:58:52.763 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.d.a(APSServiceCore.java)
06-07 17:58:52.764 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.d.c(APSServiceCore.java)
06-07 17:58:52.764 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.d$a.run(APSServiceCore.java)
06-07 17:58:52.772 31095-32257/com.freetek.deepsea W/System.err: java.lang.reflect.InvocationTargetException
06-07 17:58:52.773 31095-32257/com.freetek.deepsea W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
06-07 17:58:52.773 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.cu.a(Reflect.java)
06-07 17:58:52.773 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.ce.m(CgiManager.java)
06-07 17:58:52.773 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.ce.l(CgiManager.java)
06-07 17:58:52.773 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.ce.f(CgiManager.java)
06-07 17:58:52.773 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.bv.G(APS.java)
06-07 17:58:52.773 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.bv.a(APS.java)
06-07 17:58:52.773 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.d.a(APSServiceCore.java)
06-07 17:58:52.773 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.d.c(APSServiceCore.java)
06-07 17:58:52.773 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.d$a.run(APSServiceCore.java)
06-07 17:58:52.774 31095-32257/com.freetek.deepsea W/System.err: Caused by: java.lang.SecurityException: getAllCellInfo: Neither user 10549 nor current process has android.permission.ACCESS_COARSE_LOCATION.
06-07 17:58:52.774 31095-32257/com.freetek.deepsea W/System.err:     at android.os.Parcel.readException(Parcel.java:1620)
06-07 17:58:52.774 31095-32257/com.freetek.deepsea W/System.err:     at android.os.Parcel.readException(Parcel.java:1573)
06-07 17:58:52.774 31095-32257/com.freetek.deepsea W/System.err:     at com.android.internal.telephony.ITelephony$Stub$Proxy.getAllCellInfo(ITelephony.java:3060)
06-07 17:58:52.774 31095-32257/com.freetek.deepsea W/System.err:     at android.telephony.TelephonyManager.getAllCellInfo(TelephonyManager.java:2899)
06-07 17:58:52.774 31095-32257/com.freetek.deepsea W/System.err:    ... 10 more
06-07 17:58:52.783 31095-32257/com.freetek.deepsea W/System.err: java.lang.SecurityException: getCellLocation: Neither user 10549 nor current process has android.permission.ACCESS_COARSE_LOCATION.
06-07 17:58:52.784 31095-32257/com.freetek.deepsea W/System.err:     at android.os.Parcel.readException(Parcel.java:1620)
06-07 17:58:52.784 31095-32257/com.freetek.deepsea W/System.err:     at android.os.Parcel.readException(Parcel.java:1573)
06-07 17:58:52.784 31095-32257/com.freetek.deepsea W/System.err:     at com.android.internal.telephony.ITelephony$Stub$Proxy.getCellLocation(ITelephony.java:2428)
06-07 17:58:52.784 31095-32257/com.freetek.deepsea W/System.err:     at android.telephony.TelephonyManager.getCellLocation(TelephonyManager.java:831)
06-07 17:58:52.784 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.ce.d(CgiManager.java)
06-07 17:58:52.784 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.bv.G(APS.java)
06-07 17:58:52.784 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.bv.a(APS.java)
06-07 17:58:52.784 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.d.a(APSServiceCore.java)
06-07 17:58:52.784 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.d.c(APSServiceCore.java)
06-07 17:58:52.784 31095-32257/com.freetek.deepsea W/System.err:     at com.loc.d$a.run(APSServiceCore.java)

问题原因

Android M(版本号6.0 api:23)对原来的权限系统做了升级。在6.0之前,Android系统的app的权限是在安装的时候申请的,用户同意安装后,无需再次申请。

这样的的设计系统有明显的弊端。用户安装时被app的功能吸引,不会仔细阅读权限,一般都直接点击安装了,甚至有些应用基本上申请了app级别的所有权限。这样由权限来保障的安全系统几乎就不起作用了。

所以在很多第三方开发的Android系统里面,会对一些敏感权限,如 地理位置获取、打电话、发短信 进行限制,当app执行相关api时,会弹出提醒,让用户确认是否可行。

定位提醒.png

6.0上Google也试图来解决这个问题,但是它的解决方案比第三方要粗暴——开发者必须在调用接口前再次确定权限,否则直接拒绝。所以就出现了一开始的那个错误

java.lang.SecurityException: getCellLocation: Neither user 10549 nor current process has android.permission.ACCESS_COARSE_LOCATION.

吐槽一下:这个解决方式太坑爹了,原生系统应该向miui它们学学,对开发者友好一点。

问题解决

解决方案有两种:

  1. 不要用23的sdk编译,即 targetSdkVersion和compileSdkVersion不要等于23。基于兼容性原则,Android对用23已下sdk编译的app依然使用旧的权限模型。

  2. 自己在需要用到权限前进行权限判断,提醒用户打开相应的权限。相关代码参考github的开源工程PermissionsChecker

Panda
2016-06-07

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容