Flutter: Как избежать запроса разрешений у средства выбора системных папок?Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Flutter: Как избежать запроса разрешений у средства выбора системных папок?

Сообщение Anonymous »

Я использую средство выбора системных папок для хранения файла документа, но всякий раз, когда я выбираю папку, нажимаю «ИСПОЛЬЗОВАТЬ ЭТУ ПАПКУ», запрашивая разрешение. Я хочу, чтобы если я предоставил разрешение для какой-либо папки, то не спрашивайте разрешения для этой конкретной папки. .
Да, если пользователь выберет другую папку, повторите приведенные выше условия еще раз.
Я хочу, если я разрешаю одно это разрешение, тогда всякий раз, когда захожу на эту страницу и нажимаю «ИСПОЛЬЗОВАТЬ ЭТУ ПАПКУ».
нет спросите еще раз об этом разрешении.
Я использовал для этого SharedPreferences, но после его использования я не могу снова открыть селектор файлов. Он дает мне ранее сохраненную папку SharedPreferences. Предположим, что пользователь хочет выбрать другую папку, в этом случае это происходит неправильно.
используйте эту платформу доступа к хранилищу
Это код файла Kotlin

Код: Выделить всё

import android.app.Activity
import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
private val CHANNEL = "com.example.folder"
private val REQUEST_CODE_OPEN_DOCUMENT_TREE = 1001
private lateinit var sharedPreferences: android.content.SharedPreferences
private var resultCallback: MethodChannel.Result? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

sharedPreferences = getSharedPreferences("folder_picker_prefs", Context.MODE_PRIVATE)

// Ensure flutterEngine and dartExecutor are non-null before initializing the MethodChannel
val messenger = flutterEngine?.dartExecutor?.binaryMessenger
if (messenger != null) {
MethodChannel(messenger, CHANNEL).setMethodCallHandler { call, result ->
resultCallback = result
when (call.method) {
"pickOrGetFolder" -> handlePickOrGetFolder()
else -> result.notImplemented()
}
}
} else {
Log.e("MainActivity", "BinaryMessenger is null.  Cannot initialize MethodChannel.")
}
}

private fun handlePickOrGetFolder() {
val savedUriString = sharedPreferences.getString("selected_folder_uri", null)

if (savedUriString != null) {
// Folder URI exists; check if permissions are still valid
val savedUri = Uri.parse(savedUriString)
val hasPermissions = contentResolver.persistedUriPermissions.any {
it.uri == savedUri &&
it.isReadPermission &&
it.isWritePermission
}

if (hasPermissions) {
// Permissions are valid, return the saved URI to Flutter
resultCallback?.success(savedUriString)
} else {
// Permissions are missing; remove saved URI and ask for folder selection again
sharedPreferences.edit().remove("selected_folder_uri").apply()
openFolderPicker()
}
} else {
// No folder URI exists; open folder picker for the first time
openFolderPicker()
}
}

private fun openFolderPicker() {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
addFlags(
Intent.FLAG_GRANT_READ_URI_PERMISSION or
Intent.FLAG_GRANT_WRITE_URI_PERMISSION or
Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
)
}
startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_OPEN_DOCUMENT_TREE && resultCode == Activity.RESULT_OK) {
val uri = data?.data
if (uri != null) {
// Persist permissions for the selected folder
contentResolver.takePersistableUriPermission(
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
// Save the folder URI persistently
sharedPreferences.edit().putString("selected_folder_uri", uri.toString()).apply()

// Return the folder URI to Flutter
resultCallback?.success(uri.toString())
} else {
// If no folder was selected, return an error to Flutter
resultCallback?.error("FOLDER_SELECTION_CANCELLED", "No folder was selected.", null)
}
}
}
}
это флаттер-код

Код: Выделить всё

class FolderPickerScreen extends StatefulWidget {
@override
_FolderPickerScreenState createState() => _FolderPickerScreenState();
}

class _FolderPickerScreenState extends State {
static const platform = MethodChannel('com.example.folder');
String folderPath = "No folder selected.";

Future pickFolder() async {
try {
final String? result = await platform.invokeMethod('pickOrGetFolder');
setState(() {
folderPath = result ?? "No folder selected.";
});
} on PlatformException catch (e) {
setState(() {
folderPath = "Error: ${e.message}";
});
}
}

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("Folder Picker")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(folderPath),
ElevatedButton(
onPressed: pickFolder,
child: Text("Pick Folder"),
),
],
),
),
),
);
}
}
в этом коде я использую SharedPreference, но он мне не нужен, потому что с его помощью я не могу открыть средство выбора папок в системе.
Изображение


Подробнее здесь: https://stackoverflow.com/questions/793 ... der-picker
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»