Fix storage permission flow to direct user to settings

- Replace READ_EXTERNAL_STORAGE permission with all files access check
- Open app settings when permission is needed so user can grant it
- Check permission status when returning from settings
- Launch file picker automatically if permission is granted
This commit is contained in:
2025-12-27 18:58:58 -05:00
parent 4a7a48c9a4
commit d9052454fe

View File

@@ -1,6 +1,10 @@
package com.mattintech.simplelogupload.ui.screens.tabs package com.mattintech.simplelogupload.ui.screens.tabs
import android.Manifest import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
import android.widget.Toast import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
@@ -16,6 +20,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.mattintech.simplelogupload.ui.components.UploadParamsDialog import com.mattintech.simplelogupload.ui.components.UploadParamsDialog
import com.mattintech.simplelogupload.ui.components.UploadResultDialog import com.mattintech.simplelogupload.ui.components.UploadResultDialog
import com.mattintech.simplelogupload.util.PermissionUtil
import com.mattintech.simplelogupload.viewmodel.MainViewModel import com.mattintech.simplelogupload.viewmodel.MainViewModel
/** /**
@@ -31,6 +36,7 @@ fun GeneralUploadTab(
viewModel: MainViewModel viewModel: MainViewModel
) { ) {
val context = LocalContext.current val context = LocalContext.current
val activity = context as Activity
val uiState by viewModel.uiState.collectAsState() val uiState by viewModel.uiState.collectAsState()
// File picker launcher // File picker launcher
@@ -42,16 +48,17 @@ fun GeneralUploadTab(
} }
} }
// Storage permission launcher // Settings launcher for when user returns from granting all files access
val storagePermissionLauncher = rememberLauncherForActivityResult( val settingsLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestPermission() contract = ActivityResultContracts.StartActivityForResult()
) { isGranted -> ) { _ ->
if (isGranted) { // Check if permission was granted after returning from settings
if (PermissionUtil.hasAllFilesAccessPermission()) {
filePickerLauncher.launch("*/*") filePickerLauncher.launch("*/*")
} else { } else {
Toast.makeText( Toast.makeText(
context, context,
"Storage permission is required to select files", "All files access permission is required to select files",
Toast.LENGTH_LONG Toast.LENGTH_LONG
).show() ).show()
} }
@@ -102,7 +109,25 @@ fun GeneralUploadTab(
// Select file button // Select file button
Button( Button(
onClick = { onClick = {
storagePermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) if (PermissionUtil.hasAllFilesAccessPermission()) {
filePickerLauncher.launch("*/*")
} else {
// Request all files access permission by opening settings
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
try {
val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
intent.data = Uri.parse("package:" + context.packageName)
settingsLauncher.launch(intent)
} catch (e: Exception) {
// Fallback to general all files access settings
val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
settingsLauncher.launch(intent)
}
} else {
// On older Android versions, just launch file picker
filePickerLauncher.launch("*/*")
}
}
}, },
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
enabled = !uiState.isLoading enabled = !uiState.isLoading