diff --git a/src/androidTest/java/com/nextcloud/client/GrantStoragePermissionRule.kt b/src/androidTest/java/com/nextcloud/client/GrantStoragePermissionRule.kt index 1fb15792cf..58b7a76500 100644 --- a/src/androidTest/java/com/nextcloud/client/GrantStoragePermissionRule.kt +++ b/src/androidTest/java/com/nextcloud/client/GrantStoragePermissionRule.kt @@ -21,6 +21,7 @@ package com.nextcloud.client +import android.os.Build import androidx.test.rule.GrantPermissionRule import com.owncloud.android.utils.PermissionUtil import org.junit.rules.TestRule @@ -29,6 +30,15 @@ class GrantStoragePermissionRule private constructor() { companion object { @JvmStatic - fun grant(): TestRule = GrantPermissionRule.grant(PermissionUtil.getExternalStoragePermission()) + fun grant(): TestRule = when { + Build.VERSION.SDK_INT < Build.VERSION_CODES.R -> GrantPermissionRule.grant( + PermissionUtil + .getExternalStoragePermission() + ) + else -> { + // This rule does nothing. For now, MANAGE_EXTERNAL_STORAGE must be granted manually + TestRule { base, _ -> base } + } + } } } diff --git a/src/debug/AndroidManifest.xml b/src/debug/AndroidManifest.xml index 6bbe3d6959..99a649c542 100644 --- a/src/debug/AndroidManifest.xml +++ b/src/debug/AndroidManifest.xml @@ -4,14 +4,6 @@ - - - - - diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index bb3fa38922..c40d62425c 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -32,7 +32,10 @@ android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" tools:ignore="ScopedStorage" /> - + + diff --git a/src/main/java/com/owncloud/android/utils/PermissionUtil.kt b/src/main/java/com/owncloud/android/utils/PermissionUtil.kt index c0b5d06c72..d48198d80d 100644 --- a/src/main/java/com/owncloud/android/utils/PermissionUtil.kt +++ b/src/main/java/com/owncloud/android/utils/PermissionUtil.kt @@ -24,8 +24,13 @@ package com.owncloud.android.utils import android.Manifest import android.app.Activity import android.content.Context +import android.content.Intent import android.content.pm.PackageManager +import android.net.Uri import android.os.Build +import android.os.Environment +import android.provider.Settings +import androidx.annotation.RequiresApi import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat @@ -40,6 +45,8 @@ object PermissionUtil { const val PERMISSIONS_READ_CALENDAR_AUTOMATIC = 6 const val PERMISSIONS_WRITE_CALENDAR = 7 + const val REQUEST_CODE_MANAGE_ALL_FILES = 19203 + /** * Wrapper method for ContextCompat.checkSelfPermission(). * Determine whether *the app* has been granted a particular permission. @@ -75,8 +82,8 @@ object PermissionUtil { */ @JvmStatic fun getExternalStoragePermission(): String = when { - Build.VERSION.SDK_INT < Build.VERSION_CODES.R -> Manifest.permission.WRITE_EXTERNAL_STORAGE - else -> Manifest.permission.READ_EXTERNAL_STORAGE + Build.VERSION.SDK_INT > Build.VERSION_CODES.R -> Manifest.permission.MANAGE_EXTERNAL_STORAGE + else -> Manifest.permission.WRITE_EXTERNAL_STORAGE } /** @@ -85,8 +92,10 @@ object PermissionUtil { * @return `true` if app has the permission, or `false` if not. */ @JvmStatic - fun checkExternalStoragePermission(context: Context): Boolean = - ContextCompat.checkSelfPermission(context, getExternalStoragePermission()) == PackageManager.PERMISSION_GRANTED + fun checkExternalStoragePermission(context: Context): Boolean = when { + Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> Environment.isExternalStorageManager() + else -> checkSelfPermission(context, getExternalStoragePermission()) + } /** * Request relevant external storage permission depending on SDK. @@ -94,11 +103,23 @@ object PermissionUtil { * @param activity The target activity. */ @JvmStatic - fun requestExternalStoragePermission(activity: Activity) { - ActivityCompat.requestPermissions( - activity, arrayOf(getExternalStoragePermission()), - PERMISSIONS_EXTERNAL_STORAGE - ) + fun requestExternalStoragePermission(activity: Activity) = when { + Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> requestManageFilesPermission(activity) + else -> { + ActivityCompat.requestPermissions( + activity, arrayOf(getExternalStoragePermission()), + PERMISSIONS_EXTERNAL_STORAGE + ) + } + } + + @RequiresApi(Build.VERSION_CODES.R) + private fun requestManageFilesPermission(activity: Activity) { + val intent = Intent().apply { + action = Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION + data = Uri.parse("package:${activity.applicationContext.packageName}") + } + activity.startActivityForResult(intent, REQUEST_CODE_MANAGE_ALL_FILES) } /**