Ответ
Работа с разрешениями — одна из ключевых платформенно-зависимых задач. Во Flutter мы используем пакет permission_handler, но важно понимать различия в поведении ОС.
Android:
- Объявление в манифесте: Все разрешения должны быть объявлены в
android/app/src/main/AndroidManifest.xml. - Runtime-запрос: "Опасные" разрешения (камера, контакты, местоположение, хранилище) требуют запроса во время работы приложения. Пользователь может ответить "Разрешить" или "Запретить".
- Scoped Storage (Android 10+): Доступ к общему хранилищу сильно ограничен. Для выбора файлов используется системный пикер (
file_picker), а для папок может потребоваться специальное разрешениеMANAGE_EXTERNAL_STORAGE.
iOS:
- Объявление в Info.plist: Необходимо добавить соответствующие ключи (например,
NSLocationWhenInUseUsageDescription) вios/Runner/Info.plistс описанием причины запроса. - Runtime-запрос: Запрос происходит один раз при первом обращении к функционалу. Пользователь может выбрать "Разрешить один раз", "Разрешить при использовании приложения" или "Запретить".
- Повторный запрос: Если пользователь запретил доступ, приложение может только перенаправить его в настройки системы (
openAppSettings()).
Пример кода с permission_handler:
import 'package:permission_handler/permission_handler.dart';
Future<bool> requestCameraPermission() async {
// Проверяем статус
var status = await Permission.camera.status;
if (status.isDenied) {
// Запрашиваем разрешение (на iOS может показать диалог, на Android — системное окно)
status = await Permission.camera.request();
}
if (status.isPermanentlyDenied) {
// Пользователь нажал "Не спрашивать снова" (Android) или запретил (iOS)
// Открываем настройки приложения
await openAppSettings();
}
return status.isGranted;
}
Ключевое отличие: На Android логика "разрешить один раз" отсутствует, а управление разрешениями более детализировано (например, можно запросить доступ только к фотографиям, а не ко всему хранилищу). На iOS критически важно заполнить Info.plist, иначе разрешение не будет запрошено, а функционал просто не сработает.