Как я могу открыть файл (который не является изображением, видео или аудио) через приложение Flutter в Android 13? ⇐ Android
-
Гость
Как я могу открыть файл (который не является изображением, видео или аудио) через приложение Flutter в Android 13?
Мне нужно открыть файл, который является вложением в моем приложении. На самом деле это могут быть файлы любого типа: изображения, видео, PDF-файлы, файлы Excel... Android 13 имеет разрешения для READ_MEDIA_IMAGES, READ_MEDIA_VIDEO и READ_MEDIA_AUDIO и может запрашивать их с помощью permission_handler:
[Permission.photos, Permission.videos, Permission.audio].request()
После этого я смогу открыть загруженный файл из уведомления с помощью пакета open_file:
OpenFile.open(путь)
Но когда я пытаюсь открыть PDF-файл, он просто не работает. Это дает мне ошибку: В разрешении отказано: android.permission.MANAGE_EXTERNAL_STORAGE флаттер
Это разрешение навсегда запрещено в настройках, и пользователю не интуитивно понятно отправлять его в приложение всякий раз, когда мне нужно открыть файл из уведомления. Также я прочитал здесь, что не могу поместить его в манифест, потому что он будет отклонен Play Store.
Если вы можете мне помочь, вот код ниже:
import 'dart:io'; импортировать 'пакет:device_info_plus/device_info_plus.dart'; импортировать «пакет: flutter_local_notifications/flutter_local_notifications.dart»; импортировать «пакет: open_file/open_file.dart»; импортировать «пакет:pagedesk/data/model/ticket/attachemnt_item.dart»; импортировать «пакет:pagedesk/data/network/firebase_api.dart»; импортировать «пакет:pagedesk/utils/Utils.dart»; импортировать «пакет:pagedesk/view_model/ticket_attachemnts_view_model.dart»; импортировать «пакет:path_provider/path_provider.dart»; импортировать 'пакет:permission_handler/permission_handler.dart'; Уведомления класса { интервал МаксПрогресс = 5; Bool isCompleted = ложь; Будущее getDownloadNotification( Элемент AttachemntItem, Загрузка строкиText, Загрузка строкиCompletedText, Строка загрузкиFaildMessage, Строка cantOpenFailMessage, TicketAttachemntsViewModel viewModel) async { окончательный вариант AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails( 'имя', 'имя', ChannelDescription: 'Описание канала прогресса', каналШовбадж: ложь, важность: Важность.макс, приоритет: Приоритет.высокий, onlyAlertOnce: правда, шоуПрогресс: ложь, ); окончательный NotificationDetails NotificationDetails = NotificationDetails (android: androidNotificationDetails); Строка newPath = ""; Каталог каталогов; пытаться { если (Platform.isAndroid) { если (ожидаем requestStoragePermissions()) { каталог = (ожидайте getExternalStorageDirectory())!; печать (каталог); List paths =directory.path.split("/"); for (int x = 1; x { если (значение!= ноль) { file.writeAsBytes(значение), isCompleted = правда, FirebaseApi.localNotifications.cancel(item.id), FirebaseApi.localNotifications.show(item.id, item.name, скачатьCompletedText, NotificationDetails, полезная нагрузка: file.path) } еще { isCompleted = ложь, FirebaseApi.localNotifications.cancel(item.id), FirebaseApi.localNotifications.show(item.id, item.name, downoadFaildMessage, NotificationDetails, полезная нагрузка: ноль) } }); } поймать (е) { печать('ОШИБКА'); } } } void openFile (String path, String cantOpenFileMessage) async { пытаться { конечный результат = ожидание OpenFile.open(путь); if (result.type == ResultType.done) { print('Файл успешно открыт'); } else if (result.type == ResultType.noAppToOpen) { Utils.toastMessage(cantOpenFileMessage); } еще { Utils.toastMessage("Невозможно открыть файл через это приложение."); } } поймать (е) { print('Ошибка открытия файла: $e'); } } Future _requestPermission (разрешение) async { если (ожидайте разрешения.isGranted) { вернуть истину; } Еще если (ожидайте разрешения.isPermanallyDenied) { OpenAppSettings(); вернуть ложь; } еще { результат вар = ждут разрешения.запрос(); если (результат == PermissionStatus.granted) { вернуть истину; } } вернуть ложь; } Будущее requestStoragePermissions() асинхронный { Список разрешений = []; окончательное устройствоInfo = ждут DeviceInfoPlugin().androidInfo; если (deviceInfo.version.sdkInt > 32) { разрешения = [Разрешение.фото, Разрешение.видео, Разрешение.аудио]; } еще { разрешения = [Permission.storage]; } Статусы Map = ждут разрешений.запрос(); вернуть !statuses.containsKey(false); } Разрешения манифеста:
Мне нужно открыть файл, который является вложением в моем приложении. На самом деле это могут быть файлы любого типа: изображения, видео, PDF-файлы, файлы Excel... Android 13 имеет разрешения для READ_MEDIA_IMAGES, READ_MEDIA_VIDEO и READ_MEDIA_AUDIO и может запрашивать их с помощью permission_handler:
[Permission.photos, Permission.videos, Permission.audio].request()
После этого я смогу открыть загруженный файл из уведомления с помощью пакета open_file:
OpenFile.open(путь)
Но когда я пытаюсь открыть PDF-файл, он просто не работает. Это дает мне ошибку: В разрешении отказано: android.permission.MANAGE_EXTERNAL_STORAGE флаттер
Это разрешение навсегда запрещено в настройках, и пользователю не интуитивно понятно отправлять его в приложение всякий раз, когда мне нужно открыть файл из уведомления. Также я прочитал здесь, что не могу поместить его в манифест, потому что он будет отклонен Play Store.
Если вы можете мне помочь, вот код ниже:
import 'dart:io'; импортировать 'пакет:device_info_plus/device_info_plus.dart'; импортировать «пакет: flutter_local_notifications/flutter_local_notifications.dart»; импортировать «пакет: open_file/open_file.dart»; импортировать «пакет:pagedesk/data/model/ticket/attachemnt_item.dart»; импортировать «пакет:pagedesk/data/network/firebase_api.dart»; импортировать «пакет:pagedesk/utils/Utils.dart»; импортировать «пакет:pagedesk/view_model/ticket_attachemnts_view_model.dart»; импортировать «пакет:path_provider/path_provider.dart»; импортировать 'пакет:permission_handler/permission_handler.dart'; Уведомления класса { интервал МаксПрогресс = 5; Bool isCompleted = ложь; Будущее getDownloadNotification( Элемент AttachemntItem, Загрузка строкиText, Загрузка строкиCompletedText, Строка загрузкиFaildMessage, Строка cantOpenFailMessage, TicketAttachemntsViewModel viewModel) async { окончательный вариант AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails( 'имя', 'имя', ChannelDescription: 'Описание канала прогресса', каналШовбадж: ложь, важность: Важность.макс, приоритет: Приоритет.высокий, onlyAlertOnce: правда, шоуПрогресс: ложь, ); окончательный NotificationDetails NotificationDetails = NotificationDetails (android: androidNotificationDetails); Строка newPath = ""; Каталог каталогов; пытаться { если (Platform.isAndroid) { если (ожидаем requestStoragePermissions()) { каталог = (ожидайте getExternalStorageDirectory())!; печать (каталог); List paths =directory.path.split("/"); for (int x = 1; x { если (значение!= ноль) { file.writeAsBytes(значение), isCompleted = правда, FirebaseApi.localNotifications.cancel(item.id), FirebaseApi.localNotifications.show(item.id, item.name, скачатьCompletedText, NotificationDetails, полезная нагрузка: file.path) } еще { isCompleted = ложь, FirebaseApi.localNotifications.cancel(item.id), FirebaseApi.localNotifications.show(item.id, item.name, downoadFaildMessage, NotificationDetails, полезная нагрузка: ноль) } }); } поймать (е) { печать('ОШИБКА'); } } } void openFile (String path, String cantOpenFileMessage) async { пытаться { конечный результат = ожидание OpenFile.open(путь); if (result.type == ResultType.done) { print('Файл успешно открыт'); } else if (result.type == ResultType.noAppToOpen) { Utils.toastMessage(cantOpenFileMessage); } еще { Utils.toastMessage("Невозможно открыть файл через это приложение."); } } поймать (е) { print('Ошибка открытия файла: $e'); } } Future _requestPermission (разрешение) async { если (ожидайте разрешения.isGranted) { вернуть истину; } Еще если (ожидайте разрешения.isPermanallyDenied) { OpenAppSettings(); вернуть ложь; } еще { результат вар = ждут разрешения.запрос(); если (результат == PermissionStatus.granted) { вернуть истину; } } вернуть ложь; } Будущее requestStoragePermissions() асинхронный { Список разрешений = []; окончательное устройствоInfo = ждут DeviceInfoPlugin().androidInfo; если (deviceInfo.version.sdkInt > 32) { разрешения = [Разрешение.фото, Разрешение.видео, Разрешение.аудио]; } еще { разрешения = [Permission.storage]; } Статусы Map = ждут разрешений.запрос(); вернуть !statuses.containsKey(false); } Разрешения манифеста:
Мобильная версия