Skip to content

Commit

Permalink
Feat: Support missing "All files access" setting for e.g. Android TV
Browse files Browse the repository at this point in the history
Fixes: #875
  • Loading branch information
zhanghai committed Mar 10, 2024
1 parent 51f8545 commit a14e14f
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 5 deletions.
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="30" />
android:maxSdkVersion="32" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />

<!-- Shizuku requires API 23. -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ import me.zhanghai.android.files.util.isOrientationLandscape
import me.zhanghai.android.files.util.putArgs
import me.zhanghai.android.files.util.showToast
import me.zhanghai.android.files.util.startActivitySafe
import me.zhanghai.android.files.util.supportsExternalStorageManager
import me.zhanghai.android.files.util.takeIfNotEmpty
import me.zhanghai.android.files.util.valueCompat
import me.zhanghai.android.files.util.viewModels
Expand Down Expand Up @@ -1350,7 +1351,7 @@ class FileListFragment : Fragment(), BreadcrumbLayout.Listener, FileListAdapter.
if (viewModel.isStorageAccessRequested) {
return
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (Environment::class.supportsExternalStorageManager()) {
if (!Environment.isExternalStorageManager()) {
ShowRequestAllFilesAccessRationaleDialogFragment.show(this)
viewModel.isStorageAccessRequested = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@ import me.zhanghai.android.files.storage.StorageVolumeListLiveData
import me.zhanghai.android.files.util.createIntent
import me.zhanghai.android.files.util.isMounted
import me.zhanghai.android.files.util.putArgs
import me.zhanghai.android.files.util.supportsExternalStorageManager
import me.zhanghai.android.files.util.valueCompat

val navigationItems: List<NavigationItem?>
get() =
mutableListOf<NavigationItem?>().apply {
addAll(storageItems)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (Environment::class.supportsExternalStorageManager()) {
// Starting with R, we can get read/write access to non-primary storage volumes with
// MANAGE_EXTERNAL_STORAGE. However before R, we only have read-only access to them
// and need to use the Storage Access Framework instead, so hide them in this case
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Environment
import androidx.annotation.DrawableRes
import java8.nio.file.Path
import kotlinx.parcelize.Parcelize
Expand All @@ -22,6 +23,7 @@ import me.zhanghai.android.files.file.storageVolume
import me.zhanghai.android.files.provider.document.createDocumentTreeRootPath
import me.zhanghai.android.files.util.createIntent
import me.zhanghai.android.files.util.putArgs
import me.zhanghai.android.files.util.supportsExternalStorageManager
import kotlin.random.Random

@Parcelize
Expand All @@ -42,8 +44,8 @@ data class DocumentTree(
// android.os.storage.StorageVolume#equals [NewApi]
@SuppressLint("NewApi")
get() =
// We are using MANAGE_EXTERNAL_STORAGE to access all storage volumes since R.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R
// We are using MANAGE_EXTERNAL_STORAGE to access all storage volumes when supported.
if (!Environment::class.supportsExternalStorageManager()
&& uri.storageVolume.let { it != null && !it.isPrimaryCompat }) {
R.drawable.sd_card_icon_white_24dp
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2024 Hai Zhang <[email protected]>
* All Rights Reserved.
*/

package me.zhanghai.android.files.util

import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Environment
import android.provider.Settings
import androidx.annotation.ChecksSdkIntAtLeast
import androidx.annotation.RequiresApi
import me.zhanghai.android.files.app.packageManager
import kotlin.reflect.KClass

// TvSettings didn't have "All files access" page until Android 13.
@ChecksSdkIntAtLeast(Build.VERSION_CODES.R)
fun KClass<Environment>.supportsExternalStorageManager(): Boolean =
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> true
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R ->
isManageAppAllFilesAccessPermissionIntentResolved
else -> false
}

@delegate:RequiresApi(Build.VERSION_CODES.R)
private val isManageAppAllFilesAccessPermissionIntentResolved: Boolean
by lazy(LazyThreadSafetyMode.NONE) {
packageManager.resolveActivity(
Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION),
PackageManager.MATCH_DEFAULT_ONLY or PackageManager.MATCH_SYSTEM_ONLY
) != null
}

0 comments on commit a14e14f

Please sign in to comment.