You would usually need READ_EXTERNAL_STORAGE as well, so this sample code shows how to get both permissions.
NOTE: Refer to Get Photo Gps Location With Android 10 Scoped Storage.
Edit AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>
...
</manifest>
Edit Module:app
build.gradle
.
compileSdkVersion 29
defaultConfig {
...
targetSdkVersion 29
...
}
Fragment
class TestPermissionFragment : Fragment() {
companion object {
private const val REQUEST_STORAGE_PERMISSION = 1
private const val REQUEST_MEDIA_LOCATION_PERMISSION = 2
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.test_permission, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
if (hasStoragePermission()) {
if (hasMediaLocationPermission()) {
findImagesWithGpsInGallery(context!!.contentResolver)
} }
else {
requestMediaLocationPermission()
}
}
else {
requestStoragePermission()
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
// super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when(requestCode) {
REQUEST_STORAGE_PERMISSION -> {
if (grantResults.isNotEmpty() && grantResults[0] == PERMISSION_GRANTED) {
findAlbumsInPhotoGallery(context!!.contentResolver)
}
else {
val showRational =
ActivityCompat.shouldShowRequestPermissionRationale(
activity!!,
Manifest.permission.READ_EXTERNAL_STORAGE
)
if (showRational) {
Timber.d("Storage permission denied")
}
else {
Intent(ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:${activity!!.packageName}")).apply {
addCategory(Intent.CATEGORY_DEFAULT)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}.also { intent ->
startActivity(intent)
}
}
}
}
REQUEST_MEDIA_LOCATION_PERMISSION -> {
if (grantResults.isNotEmpty() && grantResults[0] == PERMISSION_GRANTED) {
viewModel.initGalleryMediaQquery(contentResolver)
initGalleryList()
}
else {
val showRational =
ActivityCompat.shouldShowRequestPermissionRationale(
activity!!,
Manifest.permission.ACCESS_MEDIA_LOCATION
)
if (showRational) {
viewModel.toastMessageEvent.value = Event(TextResourceString("Media Location permission denied"))
}
else {
Intent(ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:${activity!!.packageName}")).apply {
addCategory(Intent.CATEGORY_DEFAULT)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}.also { intent ->
startActivity(intent)
}
}
}
}
}
}
private fun hasStoragePermission() = ContextCompat.checkSelfPermission(
context!!,
Manifest.permission.READ_EXTERNAL_STORAGE
) == PERMISSION_GRANTED
private fun requestStoragePermission() {
if (!hasStoragePermission()) {
val permissions = arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)
ActivityCompat.requestPermissions(activity!!, permissions, REQUEST_STORAGE_PERMISSION)
}
}
private fun hasMediaLocationPermission(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// this condition is not true for below Android Q
ContextCompat.checkSelfPermission(
context!!,
Manifest.permission.ACCESS_MEDIA_LOCATION
) == PERMISSION_GRANTED
}
else true
}
private fun requestMediaLocationPermission() {
if (!hasMediaLocationPermission()) {
val permissions = arrayOf(Manifest.permission.ACCESS_MEDIA_LOCATION)
ActivityCompat.requestPermissions(activity!!, permissions,
REQUEST_MEDIA_LOCATION_PERMISSION
)
}
}
private fun findImagesWithGpsInGallery(contentResolver: ContentResolver) {
// run code which require READ_EXTERNAL_STORAGE and REQUEST_MEDIA_LOCATION_PERMISSION permission
}
}
NOTE: This is probably a better way to request 2 permissions in one function call, but the above work and I prefer the separation in code (in case I want to implement storage permission as mandatory while media location permission as optional)
NOTE: Android 10 prompt for user approval when requesting READ_EXTERNAL_STORAGE permission, but not UI is shown when requesting REQUEST_MEDIA_LOCATION_PERMISSION (as if auto approval as long as the request is made). I tested on a real Android 10 device and Android 10 emulator.