问题
We have built and deployed a location-based shopping app that worked perfectly. That is until we discovered that our app does not work on Android 5.1.1 devices due to a Security Exception thrown.
After a little research I discovered that Google has created a new method of asking for permissions at runtime but did not see any clear ways of doing that.
Can anyone give clear guidelines/lines of code of requesting permission from the user at runtime. Will the app also have to do this every time it needs the location (which in our case, is a lot);
Edit: Here's part of the manifest:
<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" />
Here's the 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
回答1:
You can use the new ContextCompat
class and the method checkSelfPermission
for checking the permission before you execute the line of code that needed a check of permission.
public static boolean isPermissionGranted(String permission, Context context){
//int res = ContextCompat.checkSelfPermission(context, permission);
return (ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED);
}
Now for permission for location you need to either check once if the user granted ACCESS_COARSE_LOCATION
or ACCESS_FINE_LOCATION
within your app.
来源:https://stackoverflow.com/questions/32619783/location-permissions-on-android-5-1