Improving support for missing MANAGE_DOCUMENTS permission
This commit is contained in:
parent
208dbd6a60
commit
1e69831244
4 changed files with 27 additions and 18 deletions
|
@ -31,12 +31,13 @@ class StorageActivity : BackupActivity() {
|
||||||
*/
|
*/
|
||||||
private val openDocumentTree = registerForActivityResult(OpenPersistableDocumentTree()) { uri ->
|
private val openDocumentTree = registerForActivityResult(OpenPersistableDocumentTree()) { uri ->
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
Log.e(TAG, "OpenDocumentTree: $uri")
|
|
||||||
val authority = uri.authority ?: throw AssertionError("No authority in $uri")
|
val authority = uri.authority ?: throw AssertionError("No authority in $uri")
|
||||||
|
// we are most likely not allowed to resolve storage roots,
|
||||||
|
// but being the optimists we are, we are still trying...
|
||||||
val storageRoot = StorageRootResolver.getStorageRoots(this, authority).getOrNull(0)
|
val storageRoot = StorageRootResolver.getStorageRoots(this, authority).getOrNull(0)
|
||||||
if (storageRoot == null) {
|
if (storageRoot == null) {
|
||||||
viewModel.onSafOptionChosen(
|
val fakeRoot = StorageRootResolver.getFakeStorageRootForUri(this, uri)
|
||||||
StorageRootResolver.getFakeStorageRootForUri(this, uri))
|
viewModel.onSafOptionChosen(fakeRoot)
|
||||||
viewModel.onUriPermissionResultReceived(uri)
|
viewModel.onUriPermissionResultReceived(uri)
|
||||||
} else {
|
} else {
|
||||||
viewModel.onSafOptionChosen(storageRoot)
|
viewModel.onSafOptionChosen(storageRoot)
|
||||||
|
@ -58,11 +59,11 @@ class StorageActivity : BackupActivity() {
|
||||||
}
|
}
|
||||||
viewModel.isSetupWizard = isSetupWizard()
|
viewModel.isSetupWizard = isSetupWizard()
|
||||||
|
|
||||||
viewModel.locationSet.observeEvent(this, {
|
viewModel.locationSet.observeEvent(this) {
|
||||||
showFragment(StorageCheckFragment.newInstance(getCheckFragmentTitle()), true)
|
showFragment(StorageCheckFragment.newInstance(getCheckFragmentTitle()), true)
|
||||||
})
|
}
|
||||||
|
|
||||||
viewModel.locationChecked.observeEvent(this, { result ->
|
viewModel.locationChecked.observeEvent(this) { result ->
|
||||||
val errorMsg = result.errorMsg
|
val errorMsg = result.errorMsg
|
||||||
if (errorMsg == null) {
|
if (errorMsg == null) {
|
||||||
setResult(RESULT_OK)
|
setResult(RESULT_OK)
|
||||||
|
@ -70,7 +71,7 @@ class StorageActivity : BackupActivity() {
|
||||||
} else {
|
} else {
|
||||||
onInvalidLocation(errorMsg)
|
onInvalidLocation(errorMsg)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
if (canUseStorageRootsFragment()) {
|
if (canUseStorageRootsFragment()) {
|
||||||
|
|
|
@ -95,9 +95,9 @@ internal class StorageOptionsFragment : Fragment(), StorageOptionClickedListener
|
||||||
|
|
||||||
listView.adapter = adapter
|
listView.adapter = adapter
|
||||||
|
|
||||||
viewModel.storageOptions.observe(viewLifecycleOwner, { roots ->
|
viewModel.storageOptions.observe(viewLifecycleOwner) { roots ->
|
||||||
onRootsLoaded(roots)
|
onRootsLoaded(roots)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.stevesoltys.seedvault.ui.storage
|
package com.stevesoltys.seedvault.ui.storage
|
||||||
|
|
||||||
|
import android.Manifest.permission.MANAGE_DOCUMENTS
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
|
@ -58,18 +59,22 @@ internal object StorageRootResolver {
|
||||||
return roots
|
return roots
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for getting a SafOption when we lack [MANAGE_DOCUMENTS],
|
||||||
|
* since we are not allowed to use [getStorageRoots] in this case.
|
||||||
|
*/
|
||||||
fun getFakeStorageRootForUri(context: Context, uri: Uri): SafOption {
|
fun getFakeStorageRootForUri(context: Context, uri: Uri): SafOption {
|
||||||
|
val authority = uri.authority ?: throw AssertionError("No authority in $uri")
|
||||||
return SafOption(
|
return SafOption(
|
||||||
authority = AUTHORITY_STORAGE,
|
authority = authority,
|
||||||
rootId = "fake",
|
rootId = ROOT_ID_DEVICE,
|
||||||
documentId = "fake",
|
documentId = DocumentsContract.getTreeDocumentId(uri),
|
||||||
// TODO: Use something other than the USB icon?
|
icon = getIcon(context, authority, ROOT_ID_DEVICE, 0),
|
||||||
icon = getIcon(context, AUTHORITY_STORAGE, "usb", 0),
|
|
||||||
title = context.getString(R.string.storage_user_selected_location_title),
|
title = context.getString(R.string.storage_user_selected_location_title),
|
||||||
summary = context.getString(R.string.storage_user_selected_location_summary),
|
summary = "Please open a bug if you see this",
|
||||||
availableBytes = null,
|
availableBytes = null,
|
||||||
isUsb = false, // TODO: Check this if possible instead of forcing false
|
isUsb = false, // FIXME not supported without MANAGE_DOCUMENTS permission
|
||||||
requiresNetwork = false, // TODO: Check this if possible instead of forcing false
|
requiresNetwork = authority != AUTHORITY_STORAGE && authority != AUTHORITY_DOWNLOADS,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,15 +128,19 @@ internal object StorageRootResolver {
|
||||||
authority == AUTHORITY_STORAGE && rootId == ROOT_ID_DEVICE -> {
|
authority == AUTHORITY_STORAGE && rootId == ROOT_ID_DEVICE -> {
|
||||||
context.getDrawable(R.drawable.ic_phone_android)
|
context.getDrawable(R.drawable.ic_phone_android)
|
||||||
}
|
}
|
||||||
|
|
||||||
authority == AUTHORITY_STORAGE && rootId != ROOT_ID_HOME -> {
|
authority == AUTHORITY_STORAGE && rootId != ROOT_ID_HOME -> {
|
||||||
context.getDrawable(R.drawable.ic_usb)
|
context.getDrawable(R.drawable.ic_usb)
|
||||||
}
|
}
|
||||||
|
|
||||||
authority == AUTHORITY_NEXTCLOUD -> {
|
authority == AUTHORITY_NEXTCLOUD -> {
|
||||||
context.getDrawable(R.drawable.nextcloud)
|
context.getDrawable(R.drawable.nextcloud)
|
||||||
}
|
}
|
||||||
|
|
||||||
authority == AUTHORITY_DAVX5 -> {
|
authority == AUTHORITY_DAVX5 -> {
|
||||||
context.getDrawable(R.drawable.davx5)
|
context.getDrawable(R.drawable.davx5)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,6 @@
|
||||||
<string name="storage_fragment_warning">People with access to your storage location can learn which apps you use, but do not get access to the apps\' data.</string>
|
<string name="storage_fragment_warning">People with access to your storage location can learn which apps you use, but do not get access to the apps\' data.</string>
|
||||||
<string name="storage_fragment_warning_delete">Existing backups in this location will be deleted.</string>
|
<string name="storage_fragment_warning_delete">Existing backups in this location will be deleted.</string>
|
||||||
<string name="storage_user_selected_location_title">User-chosen location</string>
|
<string name="storage_user_selected_location_title">User-chosen location</string>
|
||||||
<string name="storage_user_selected_location_summary">Chosen using the folder browser</string>
|
|
||||||
<string name="storage_fake_drive_title">USB flash drive</string>
|
<string name="storage_fake_drive_title">USB flash drive</string>
|
||||||
<string name="storage_fake_drive_summary">Needs to be plugged in</string>
|
<string name="storage_fake_drive_summary">Needs to be plugged in</string>
|
||||||
<string name="storage_available_bytes"><xliff:g example="1 GB" id="size">%1$s</xliff:g> free</string>
|
<string name="storage_available_bytes"><xliff:g example="1 GB" id="size">%1$s</xliff:g> free</string>
|
||||||
|
|
Loading…
Reference in a new issue