Эх сурвалжийг харах

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>
Álvaro Brey Vilas 3 жил өмнө
parent
commit
a0b85cac71

+ 11 - 1
src/androidTest/java/com/nextcloud/client/GrantStoragePermissionRule.kt

@@ -21,6 +21,7 @@
 
 
 package com.nextcloud.client
 package com.nextcloud.client
 
 
+import android.os.Build
 import androidx.test.rule.GrantPermissionRule
 import androidx.test.rule.GrantPermissionRule
 import com.owncloud.android.utils.PermissionUtil
 import com.owncloud.android.utils.PermissionUtil
 import org.junit.rules.TestRule
 import org.junit.rules.TestRule
@@ -29,6 +30,15 @@ class GrantStoragePermissionRule private constructor() {
 
 
     companion object {
     companion object {
         @JvmStatic
         @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 }
+            }
+        }
     }
     }
 }
 }

+ 0 - 8
src/debug/AndroidManifest.xml

@@ -4,14 +4,6 @@
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
     <uses-permission android:name="android.permission.WAKE_LOCK"/>
     <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 -->
     <!-- Allows changing locales -->
     <uses-permission android:name="android.permission.CHANGE_CONFIGURATION"
     <uses-permission android:name="android.permission.CHANGE_CONFIGURATION"
         tools:ignore="ProtectedPermissions" />
         tools:ignore="ProtectedPermissions" />

+ 4 - 1
src/main/AndroidManifest.xml

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

+ 30 - 9
src/main/java/com/owncloud/android/utils/PermissionUtil.kt

@@ -24,8 +24,13 @@ package com.owncloud.android.utils
 import android.Manifest
 import android.Manifest
 import android.app.Activity
 import android.app.Activity
 import android.content.Context
 import android.content.Context
+import android.content.Intent
 import android.content.pm.PackageManager
 import android.content.pm.PackageManager
+import android.net.Uri
 import android.os.Build
 import android.os.Build
+import android.os.Environment
+import android.provider.Settings
+import androidx.annotation.RequiresApi
 import androidx.core.app.ActivityCompat
 import androidx.core.app.ActivityCompat
 import androidx.core.content.ContextCompat
 import androidx.core.content.ContextCompat
 
 
@@ -40,6 +45,8 @@ object PermissionUtil {
     const val PERMISSIONS_READ_CALENDAR_AUTOMATIC = 6
     const val PERMISSIONS_READ_CALENDAR_AUTOMATIC = 6
     const val PERMISSIONS_WRITE_CALENDAR = 7
     const val PERMISSIONS_WRITE_CALENDAR = 7
 
 
+    const val REQUEST_CODE_MANAGE_ALL_FILES = 19203
+
     /**
     /**
      * Wrapper method for ContextCompat.checkSelfPermission().
      * Wrapper method for ContextCompat.checkSelfPermission().
      * Determine whether *the app* has been granted a particular permission.
      * Determine whether *the app* has been granted a particular permission.
@@ -75,8 +82,8 @@ object PermissionUtil {
      */
      */
     @JvmStatic
     @JvmStatic
     fun getExternalStoragePermission(): String = when {
     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.
      * @return `true` if app has the permission, or `false` if not.
      */
      */
     @JvmStatic
     @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.
      * Request relevant external storage permission depending on SDK.
@@ -94,11 +103,23 @@ object PermissionUtil {
      * @param activity The target activity.
      * @param activity The target activity.
      */
      */
     @JvmStatic
     @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)
     }
     }
 
 
     /**
     /**