Android 5.1中的位置权限

3
我们已经开发并部署了一款基于位置的购物应用程序,运行良好。但是我们发现该应用程序无法在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 ComponentInfo{com.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

经过一些研究,我发现Google创建了一种新的在运行时请求权限的方法--不适用于Android 5.1。这个方法要等到Android 6.0才能使用。你可能希望考虑发布一个“最小、完整和可验证的示例”来解决你的问题,在这种情况下,包括你的代码、你在清单中拥有的权限和SecurityException的堆栈跟踪。 - CommonsWare
我已经包含了清单和日志记录的部分。谢谢。 - Visionwriter
你在测试哪个设备?也许这是一个设备特定的问题。 - CommonsWare
发现你关于那个是Marshmallow问题的说法是正确的。我想问题出在我对其中一个位置权限设置了最大SDK限制,后来在寻找问题时将其删除了。不过,我还将SDK更新为API 23,这搞砸了我的项目的其他部分。 - Visionwriter
嘿@CommonsWare。请帮我解决这个问题http://stackoverflow.com/questions/32674521/action-bar-drawer-toggle-seizes-to-work-with-api-23-appcompat-v7 - Visionwriter
1个回答

3

在执行需要权限检查的代码行之前,您可以使用新的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 。只需要检查一次即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接