問題描述
高德地圖晌涕,在我的小米4(Android 6.0)上出現(xiàn)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)對原來的權限系統(tǒng)做了升級临梗。在6.0之前,Android系統(tǒng)的app的權限是在安裝的時候申請的,用戶同意安裝后刚陡,無需再次申請。
這樣的的設計系統(tǒng)有明顯的弊端株汉。用戶安裝時被app的功能吸引筐乳,不會仔細閱讀權限,一般都直接點擊安裝了乔妈,甚至有些應用基本上申請了app級別的所有權限蝙云。這樣由權限來保障的安全系統(tǒng)幾乎就不起作用了。
所以在很多第三方開發(fā)的Android系統(tǒng)里面路召,會對一些敏感權限勃刨,如 地理位置獲取、打電話股淡、發(fā)短信 進行限制朵你,當app執(zhí)行相關api時,會彈出提醒揣非,讓用戶確認是否可行。
6.0上Google也試圖來解決這個問題躲因,但是它的解決方案比第三方要粗暴——開發(fā)者必須在調用接口前再次確定權限早敬,否則直接拒絕。所以就出現(xiàn)了一開始的那個錯誤
java.lang.SecurityException: getCellLocation: Neither user 10549 nor current process has android.permission.ACCESS_COARSE_LOCATION.
吐槽一下:這個解決方式太坑爹了大脉,原生系統(tǒng)應該向miui它們學學搞监,對開發(fā)者友好一點。
問題解決
解決方案有兩種:
不要用23的sdk編譯镰矿,即 targetSdkVersion和compileSdkVersion不要等于23琐驴。基于兼容性原則,Android對用23已下sdk編譯的app依然使用舊的權限模型绝淡。
自己在需要用到權限前進行權限判斷宙刘,提醒用戶打開相應的權限。相關代碼參考github的開源工程PermissionsChecker牢酵。
Panda
2016-06-07