I'm trying to implement the ACCESS_MEDIA_LOCATION permission for Android 10 in order to access the location of a photo.
First the app requests READ_EXTERNAL_STORAGE permission in order to access the photo using MediaStore.
Then the app reads the photo's location, using ExifInterface. In Android 10 the ExifInterface fails because it doesn't have permission.
I've tried to add a permission request for ACCESS_MEDIA_LOCATION, but no permission request box comes up. However, the permission is subsequently granted!
If I request the ACCESS_MEDIA_LOCATION first before getting READ_EXTERNAL_STORAGE permission, then the permission request box does come up.
If I then request READ_EXTERNAL_STORAGE permission, the permission request box then doesn't come up, but again, permission is subsequently granted. (I know it doesn't make sense to do it that way round, but I just wanted to see what happened.)
I'm really confused. It makes sense that the user's permission should be asked for in order to access photos' location, but why is the permission box for ACCESS_MEDIA_LOCATION not appearing if READ_EXTERNAL_STORAGE has previously been granted and why is permission being granted without the user agreeing to it?
Is there something I'm missing which will make the permission box appear?
Code snippets below.
Android Manifest:
<manifest ...>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
…
Fragment1:
public class Fragment1 extends Fragment {
…
public View onCreateView(...
…
Log.d(TAG, "Entering Fragment1 requestPermissions operation for permission READ_EXTERNAL_STORAGE");
Log.d(TAG, "Permission ACCESS_MEDIA_LOCATION, " + this.requireContext().checkSelfPermission(Manifest.permission.ACCESS_MEDIA_LOCATION));
Log.d(TAG, "Permission READ_EXTERNAL_STORAGE, " + this.requireContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
String[] permission = {Manifest.permission.READ_EXTERNAL_STORAGE};
this.requestPermissions(permission, 1);
Log.d(TAG, "Exiting Fragment1 requestPermissions operation for permission READ_EXTERNAL_STORAGE");
Log.d(TAG, "Permission ACCESS_MEDIA_LOCATION, " + this.requireContext().checkSelfPermission(Manifest.permission.ACCESS_MEDIA_LOCATION));
Log.d(TAG, "Permission READ_EXTERNAL_STORAGE, " + this.requireContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
...
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
Log.d(TAG, "Fragment1 Request Permissions callback");
for (int i = 0; i < permissions.length; i++)
Log.d(TAG, "Permission " + permissions[0] + ", " + grantResults[0] );
Log.d(TAG, "Permission ACCESS_MEDIA_LOCATION, " + this.requireContext().checkSelfPermission(Manifest.permission.ACCESS_MEDIA_LOCATION));
Log.d(TAG, "Permission READ_EXTERNAL_STORAGE, " + this.requireContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
}
Fragment2:
public class Fragment2 extends Fragment {
...
public View onCreate(...
…
Log.d(TAG, "Entering Fragment2 requestPermissions operation for permission ACCESS_MEDIA_LOCATION");
Log.d(TAG, "Permission ACCESS_MEDIA_LOCATION, " + this.requireContext().checkSelfPermission(Manifest.permission.ACCESS_MEDIA_LOCATION));
Log.d(TAG, "Permission READ_EXTERNAL_STORAGE, " + this.requireContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
String[] permission = {Manifest.permission.ACCESS_MEDIA_LOCATION};
this.requestPermissions(permission, 1); // No permission box appears here :-(
Log.d(TAG, "Exiting Fragment2 requestPermissions operation for permission ACCESS_MEDIA_LOCATION");
Log.d(TAG, "Permission ACCESS_MEDIA_LOCATION, " + this.requireContext().checkSelfPermission(Manifest.permission.ACCESS_MEDIA_LOCATION));
Log.d(TAG, "Permission READ_EXTERNAL_STORAGE, " + this.requireContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
…
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
Log.d(TAG, "Fragment2 Request Permissions callback");
for (int i = 0; i < permissions.length; i++)
Log.d(TAG, "Permission " + permissions[0] + ", " + grantResults[0] );
Log.d(TAG, "Permission ACCESS_MEDIA_LOCATION, " + this.requireContext().checkSelfPermission(Manifest.permission.ACCESS_MEDIA_LOCATION));
Log.d(TAG, "Permission READ_EXTERNAL_STORAGE, " + this.requireContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
}
When run on Nexus 6 API 29 emulator the first UI box for READ_EXTERNAL_STORAGE pops up and I tap “Allow”. I then go to the second fragment but no UI box pops up when requestPermissions called.
Here are the logs. You can see when the requestPermissions is called, the permission isn't allowed, but when it gets to the callback the permission has been granted:
2020-10-20 12:17:38.154 8830-8830/com.example.example1 D/ContentValues: Entering Fragment1 requestPermissions operation for permission READ_EXTERNAL_STORAGE
2020-10-20 12:17:38.155 8830-8830/com.example.example1 D/ContentValues: Permission ACCESS_MEDIA_LOCATION, -1
2020-10-20 12:17:38.155 8830-8830/com.example.example1 D/ContentValues: Permission READ_EXTERNAL_STORAGE, -1
2020-10-20 12:17:38.162 8830-8830/com.example.example1 D/ContentValues: Exiting Fragment1 requestPermissions operation for permission READ_EXTERNAL_STORAGE
2020-10-20 12:17:38.163 8830-8830/com.example.example1 D/ContentValues: Permission ACCESS_MEDIA_LOCATION, -1
2020-10-20 12:17:38.164 8830-8830/com.example.example1 D/ContentValues: Permission READ_EXTERNAL_STORAGE, -1
2020-10-20 12:17:49.544 8830-8830/com.example.example1 D/ContentValues: Fragment1 Request Permissions callback
2020-10-20 12:17:49.544 8830-8830/com.example.example1 D/ContentValues: Permission android.permission.READ_EXTERNAL_STORAGE, 0
2020-10-20 12:17:49.545 8830-8830/com.example.example1 D/ContentValues: Permission ACCESS_MEDIA_LOCATION, -1
2020-10-20 12:17:49.546 8830-8830/com.example.example1 D/ContentValues: Permission READ_EXTERNAL_STORAGE, 0
2020-10-20 12:17:55.312 8830-8830/com.example.example1 D/ContentValues: Entering Fragment2 requestPermissions operation for permission ACCESS_MEDIA_LOCATION
2020-10-20 12:17:55.313 8830-8830/com.example.example1 D/ContentValues: Permission ACCESS_MEDIA_LOCATION, -1
2020-10-20 12:17:55.318 8830-8830/com.example.example1 D/ContentValues: Permission READ_EXTERNAL_STORAGE, 0
2020-10-20 12:17:55.327 8830-8830/com.example.example1 D/ContentValues: Exiting Fragment2 requestPermissions operation for permission ACCESS_MEDIA_LOCATION
2020-10-20 12:17:55.328 8830-8830/com.example.example1 D/ContentValues: Permission ACCESS_MEDIA_LOCATION, -1
2020-10-20 12:17:55.329 8830-8830/com.example.example1 D/ContentValues: Permission READ_EXTERNAL_STORAGE, 0
2020-10-20 12:17:55.621 8830-8830/com.example.example1 D/ContentValues: Fragment2 Request Permissions callback
2020-10-20 12:17:55.622 8830-8830/com.example.example1 D/ContentValues: Permission android.permission.ACCESS_MEDIA_LOCATION, 0
2020-10-20 12:17:55.623 8830-8830/com.example.example1 D/ContentValues: Permission ACCESS_MEDIA_LOCATION, 0
2020-10-20 12:17:55.623 8830-8830/com.example.example1 D/ContentValues: Permission READ_EXTERNAL_STORAGE, 0