Android 5.1 上的位置权限

Posted

技术标签:

【中文标题】Android 5.1 上的位置权限【英文标题】:Location Permissions on Android 5.1 【发布时间】:2015-12-13 16:48:21 【问题描述】:

我们已经构建并部署了一个完美运行的基于位置的购物应用程序。直到我们发现由于抛出了安全异常,我们的应用程序无法在 android 5.1.1 设备上运行。

经过一番研究,我发现 Google 创建了一种在运行时请求权限的新方法,但没有看到任何明确的方法。

任何人都可以给出在运行时向用户请求权限的明确指南/代码行。应用程序是否也必须在每次需要位置时都这样做(在我们的例子中,很多);

编辑: 这是清单的一部分:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

<!-- GCM Permissions -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="com.site.app.permission.C2D_MESSAGE" />
<permission android:name="com.site.app.permission.C2D_MESSAGE"  android:protectionLevel="signature" />

这是 Logcat:

09-16 10:08:55.531: E/AndroidRuntime(22970): java.lang.RuntimeException: Unable to start activity ComponentInfocom.site.app/com.site.app.Search: java.lang.SecurityException: "passive" location provider requires ACCESS_FINE_LOCATION permission.
09-16 10:08:55.531: E/AndroidRuntime(22970):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at android.app.ActivityThread.access$800(ActivityThread.java:156)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at android.os.Handler.dispatchMessage(Handler.java:102)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at android.os.Looper.loop(Looper.java:211)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at android.app.ActivityThread.main(ActivityThread.java:5389)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at java.lang.reflect.Method.invoke(Native Method)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at java.lang.reflect.Method.invoke(Method.java:372)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
09-16 10:08:55.531: E/AndroidRuntime(22970): Caused by: java.lang.SecurityException: "passive" location provider requires ACCESS_FINE_LOCATION permission.
09-16 10:08:55.531: E/AndroidRuntime(22970):    at android.os.Parcel.readException(Parcel.java:1553)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at android.os.Parcel.readException(Parcel.java:1505)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at android.location.ILocationManager$Stub$Proxy.getLastLocation(ILocationManager.java:693)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at android.location.LocationManager.getLastKnownLocation(LocationManager.java:1184)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at com.site.app.Search.getBestLocator(Search.java:423)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at com.site.app.Search.useAndroidFinder(Search.java:563)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at com.site.app.Search.onCreate(Search.java:126)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at android.app.Activity.performCreate(Activity.java:5990)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
09-16 10:08:55.531: E/AndroidRuntime(22970):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2332)
09-16 10:08:55.531: E/AndroidRuntime(22970):    ... 10 more

【问题讨论】:

“经过一番研究,我发现谷歌创建了一种在运行时请求权限的新方法”——不适用于 Android 5.1。直到 Android 6.0 才开始生效。您可能希望考虑发布您的问题的minimal, complete, and verifiable example,在这种情况下将包括您的代码、您拥有权限的清单以及您的SecurityException 的堆栈跟踪。 我已经包含了清单和 logcat 的部分内容。谢谢。 你在什么设备上测试这个?可能是特定于设备的问题。 发现您说的是 Marshmellow 问题是对的。我认为问题在于我对其中一个位置权限设置了最大 SDK 限制,我在搜索问题时将其编辑掉了。但是,我还将我的 SDK 更新为 API 23,这搞砸了我项目的其他部分。 嘿@Co​​mmonsWare。请帮我解决这个问题***.com/questions/32674521/… 【参考方案1】:

在执行需要检查权限的代码行之前,您可以使用新的ContextCompat 类和方法checkSelfPermission 来检查权限。

public static boolean isPermissionGranted(String permission, Context context)
        //int res = ContextCompat.checkSelfPermission(context, permission);
        return (ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED);
    

现在,如果用户在您的应用中授予了ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATION,您需要检查一次,以获得位置权限。

【讨论】:

以上是关于Android 5.1 上的位置权限的主要内容,如果未能解决你的问题,请参考以下文章

权限被拒绝无法获取位置 Android

react-native中iOS上的位置权限不起作用

Android 11 用户无法授予后台位置权限?

Android 5.1 上的多个 writeDescriptor() 调用失败

无法连接到 android 5.1 上的本机本地套接字

android 5.1 WIFI图标上的感叹号及其解决办法