Ditch scoped storage, try MANAGE_EXTERNAL_STORAGE

We _are_ a file-managing app, after all.

Signed-off-by: Álvaro Brey Vilas <alvaro.brey@nextcloud.com>
This commit is contained in:
Álvaro Brey Vilas 2021-11-08 13:13:02 +01:00
parent 0f024b81e0
commit a0b85cac71
No known key found for this signature in database
GPG key ID: 2585783189A62105
4 changed files with 45 additions and 19 deletions

View file

@ -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 }
}
}
}
}

View file

@ -4,14 +4,6 @@
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<!-- Allows for storing and retrieving screenshots -->
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- Allows changing locales -->
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"
tools:ignore="ProtectedPermissions" />

View file

@ -32,7 +32,10 @@
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />

View file

@ -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)
}
/**