- Работа с камерой во Flutter
- camera
- image-picker
- Заключение
- Flutter android permission camera
- Handling Requesting for Permissions Like a Pro in Flutter
- Package(s)
- Installation
- Permissions
- iOS permissions
- Android permissions
- Requesting for Permission
- Checking if your App has been Given Permission
- Android Camera permission: Permission.camera.status returns undetermined when it should be permanentlyDenied #336
- Comments
- viplavrawal commented Jun 24, 2020
- 🐛 Bug Report
- Reproduction steps
- Actual behavior
- Expected behaviour
- Configuration
- DhavalRKansara commented Jul 1, 2020
- mvanbeusekom commented Jul 1, 2020 •
- DhavalRKansara commented Jul 6, 2020
- Arkangel12 commented Jul 15, 2020
- DhavalRKansara commented Jul 27, 2020 •
- koskimas commented Aug 5, 2020 •
- mikeesouth commented Dec 3, 2020
- Sempakonka commented Jan 4, 2021
- koskimas commented Jan 4, 2021
- yaizudamashii commented Jan 6, 2021
- yaizudamashii commented Jan 19, 2021
- moodstubos commented Feb 4, 2021 •
- RomanKapshuk commented Feb 4, 2021
- claudiowagner commented Feb 4, 2021 •
- mvanbeusekom commented Feb 4, 2021
- mvanbeusekom commented Feb 4, 2021
- moodstubos commented Feb 4, 2021 •
- yaizudamashii commented Feb 5, 2021 •
Работа с камерой во Flutter
Возможность задействовать камеру существует во многих приложениях, и мы все регулярно пользуемся ею. Во Flutter мы можем реализовать работу с камерой с помощью двух официальных плагинов:
Между ними – заметная разница, и использовать их стоит по ситуации:
- camera позволяет взаимодействовать с доступными устройству камерами из вашего приложения и выводить изображение в виджет. Хорошо подходит под задачи, когда надо «кастомизировать» работу камеры под приложение.
- image-picker запускает приложение камеры и возвращает объект типа File (изображение или видеофайл, выбранный пользователем) в ваше приложение. Также image-picker дает возможность выбора файла из имеющихся на устройстве, при этом, как и в случае камеры, запускается отдельное приложение, после чего в ваше приложение возвращается выбранный объект.
Здесь можно посмотреть исходники.
camera
1. Добавляем плагин в наш проект по инструкции
Дополнительные настройки для ОС
iOS
Добавьте следующие строки в ios/Runner/Info.plist :
Android
Убедить, что минимальная версия Android sdk в файле android/app/build.gradle 21.
Все необходимые разрешения будут запрошены при запуске приложения
Работа на эмуляторах
В случае IOS мы не можем проверить работу камеры на эмуляторе, нужно «живое» устройство.
Android генерирует некий mock (см. изображение ниже), который заменяет то, что видит объектив камеры.
В настройках эмулятора выбираем Advanced Settings и для задней камеры ставим VirtualScene .
Перезапускаем эмулятор. Теперь камера «показывает» виртуальную комнату, по которой можно передвигать с помощью мыши и wasd.
Спасибо Tonn_Tamerlan за наводку.
2. Переходим к коду. Сначала получаем все доступные камеры с помощью функции availableCameras .
Данная функция вернет массив описаний ( List ) доступных камер, где каждый элемент будет содержать имя камеры (это может быть просто индекс), тип (задняя, фронтальная, внешняя) и угол, на который надо повернуть фотографию, чтобы она отображалась в своей ориентации.
Для управления камерой нам нужен объект-контроллер типа CameraController , для определения которого надо указать одно из полученных описаний камеры и разрешение (низкое, среднее, высокое).
Далее инициализируем контроллер и после того, как убедимся, что виджет «жив», обновляем состояние этого виджета. (текст функции)
Передаем инициализированный контроллер в виджет CameraPreview
В основе CameraPreview лежит виджет Texture , отвечающий за отображение картинки с камеры. Его размеры определяются родителем, поэтому хорошо подход виджет AspectRatio , определяющий размер дочернего элемента в определенном соотношении сторон. Соотношение мы получаем из контроллера _controller.value.aspectRatio . В результате в интерфейсе получаем картинку в интерфейсе
3. Теперь мы можем сделать фотоснимок или снять видео.
а. Делаем фотографию (текст функции) с помощью метода takePicture(String path) . Он делает снимок и сохраняет по указанному пути.
Чтобы получить путь нам необходим официальный плагин path_provider и его метод getApplicationDocumentsDirectory , который вернет приватную директорию. Далее определяем имя директории по вкусу, если надо создаем ее, и выбираем имя файла:
Перед тем, как делать снимок, желательно проверить, что контроллер инициализирован и уже не делается фотография.
Снимок сделан, у нас есть путь к нему, хорошо бы посмотреть. С помощью стандартного виджета Image , объекта File и пути к файлу выводим картинку на экран.
б. При записи видео (текст функции) нам понадобятся две функции: startVideoRecording(String filePath) и stopVideoRecording() .
startVideoRecording пишет видео и сохраняет по указанному пути (полученному по такому же принципу, как и с фотографией), stopVideoRecording же просто завершает процесс записи. Перед началом записи следует убедиться, что съемка уже не идет.
В результате у нас есть сохраненное видео и путь к нему. Для его проигрывания понадобится плагин video_player. Весь код, связанный с проигрыванием видео, вынесен в отдельный файл.
image-picker
1. Добавляем плагин в наш проект по инструкции
Дополнительные настройки для ОС
iOS
Добавьте следующие строки в ios/Runner/Info.plist :
Работа на эмуляторах
В IOS мы не можем проверить работу камеры на эмуляторе, нужно «живое» устройство.
2. image-picker использует стандартное приложение для создания фото/видео или просмотра файлов. Для запуска нужного приложения необходимо воспользоваться функцией pickImage для фото или pickVideo и указать параметр source (источник).
Выбранный файл получает наше приложение, но если ничего не было выбрано, то вернется null . Для показа картинки и видео используем те же подходы, что и в случае плагина camera . Для изображений виджет Image — в этот раз не надо оборачивать в File , так как мы изначально получили объект этого типа.
Для видео плагин video_player. Весь код, связанный с проигрыванием видео, вынесен в отдельный файл.
Заключение
Как вы успели заметить, image-picker заметно проще в использовании и прекрасно подходит в тех случаях, когда просто надо передать изображение или видео приложению. camera же предоставляет нам все необходимые возможности для кастомизации работы пользователя с камерой в вашем приложении.
Спасибо, что прочитали!
Источник
Flutter android permission camera
Thank you for reading my blog posts, I am no longer publishing new content on this platform, you can find my latest content on my personal site — mainawycliffe.dev
Handling Requesting for Permissions Like a Pro in Flutter
In this lesson, we are going to look at how to request and check permissions on Android and IOS in Flutter.
Package(s)
Installation
The process of installing a flutter package is quite simple, just open the pubspec file and add the package into your dependency bloc section.
TIP: You can use caret versioning to restrict the package version to a specific major version. For instance, permission_handler: ^3.0.0 restricts it to version 3, but you will get both minor updates and patches. You can learn more about how dart pub package manager works here if you are interested.
Permissions
First, we need to determine which permissions we need, because your app needs to publicly declare the permissions it needs. Some less-sensitive permissions such as the internet, etc. are granted automatically. While other more sensitive permissions, think of Location, Contacts, etc. require user authorization before your app can use them.
iOS permissions
In iOS, this done by adding the permissions to Information Property List File i.e. info.plist , with the Permission you need being the Key, accompanied by the reason why your app needs to use the feature.
In Flutters’ case, the info.plist in the iOS/Runner directory at the root of your project. You can learn more about the info.plist here.
You can find the complete list of permissions here and guidelines for asking permission on iOS here.
Android permissions
In Android, you can achieve the same by adding the tag to the android manifest, this in the android/src/main/AndroidManifest.xml directory.
You can learn more about permission on Android here and the best practices here.
Requesting for Permission
To request permission, first you need to import the package:
And then, let say you want to request contact permission, you can do it like this. You pass a list of permissions you are requesting for, which allows you to ask for multiple permissions you need at once.
And finally, you can inspect the result to see if the user granted permission or not. The results object is an array of PermissionStatus . The key of the array is the permission you were asking.
The possible permission statuses are:
Status | Why |
---|---|
Granted | Your app has been given permission to use the feature in question |
Denied | Your app has been given permission to use the feature in question |
Disabled | Feature in question is disabled i.e. when the Location feature is disabled. |
Restricted (iOS only) | OS has restricted access to a specific feature due to something like parental controls. |
Unknown | Unknown state of permissions. |
For instance, in our example above, we can check if permission to access contacts was granted like this:
You can also use a switch statement to react to the results of your request.
Checking if your App has been Given Permission
It is important that your app can check if it has permission to access certain features. This allows your app to decide based on if the user has granted permission or not. On top of that, it can help you determine if a feature is available or disabled on the users’ device.
You can check for permission by using the checkPermissionStatus function, which accepts the Permission as a parameter.
This returns a PermissionStatus class – we saw it above – which details the status of the permission.
Some permissions such as contacts, calendar, microphone, location, etc. are common across iOS and Android. On the other hand, there are some permissions that either do not match up on both OSs. While others are just on one OS, i.e. storage, SMS, phone, etc. are only on android. You might want to determine which platform it is before requesting permission from the user.
Take a camera app, for instance, if you wanted photos to appear in the gallery, on iOS, you need photos permission while in android you need external storage permission.
And then, you can check if the user has granted your app permission:
Источник
Android Camera permission: Permission.camera.status returns undetermined when it should be permanentlyDenied #336
Comments
viplavrawal commented Jun 24, 2020
🐛 Bug Report
Permission.camera.status returns undetermined if called immediately after the user permanentlyDenies the access.
In older android versions, keeps returning undetermined for longer whiles than in android 10 when the user clicks on permanentlyDenied option.
Reproduction steps
- Request user for permission
- Permanently deny the permission from the user’s end
- Ask for permission status
Actual behavior
The permission status is returned as undetermined once.
Requesting the permission status again returns it as permanentlyDenied.
Expected behaviour
The permission status should be returned as permanentlyDenied.
Configuration
Version: ^5.0.0+hotfix.3
Platform:
- 📱 iOS
- 🤖 Android
The text was updated successfully, but these errors were encountered:
DhavalRKansara commented Jul 1, 2020
I am also facing the same issues @viplavrawal have you find any solution or workaround for the same?
mvanbeusekom commented Jul 1, 2020 •
@viplavrawal can you reproduce this bug with the latest version (5.0.1+1)? Maybe you can also check out the example App, does the problem occur there as well?
One option I am thinking is that we store information if permissions are requested before using the SharedPreferences API on Android. To do this we use the key GENERIC_PREFERENCES , does your App also save data to Android SharedPreferences and by change use the same key?
DhavalRKansara commented Jul 6, 2020
@mvanbeusekom yes, I am facing this issue with the latest version (5.0.1+1). And No we are not using GENERIC_PREFERENCES for storing any value in the shared preferences.
Also with version 4.0.0, it is working fine and the library returns me the perfect status of the permission as in case of denied and if I denied with never ask again then it returns me PermissionStatus.neverAskAgain . So may b the issues with the latest version only or something else I’m not sure about that.
Arkangel12 commented Jul 15, 2020
i just add 5.0.1+1 to my app and this is still happening i’m always receiving. PermissionStatus.undetermined any updates?
DhavalRKansara commented Jul 27, 2020 •
@mvanbeusekom Is there any update on this?
First time await Permission.camera.request() worked properly with PermissionStatus.undetermined .But after that when I deny the permission getting same permission status as PermissionStatus.undetermined and await Permission.camera.status give me below exception.
koskimas commented Aug 5, 2020 •
I also get undetermined for Permission.storage.status after I’ve denied access with «deny and never ask me again» button on android. I’m on version 5.0.1+1. I think the same thing happens for all permissions and not just camera?
mikeesouth commented Dec 3, 2020
Any news? Any workaround? This is a real pain.
Sempakonka commented Jan 4, 2021
Hi
I was not able to reproduce, but it seems a lot of people have this issue.
Maybe this solution helps.
koskimas commented Jan 4, 2021
@Sempakonka This happens on every device I’ve tested and on every app I’ve tested it in. It’s extremely weird if you are not able to reproduce this.
yaizudamashii commented Jan 6, 2021
@Sempakonka ‘s suggestion also runs permission request, resulting in the same exception.
I’m also facing this issue, while using add-to-app in Flutter. One thing I’d like to share is that Flutter shared_preferences also doesn’t work with add-to-app, maybe there is something with using Android’s shared preferences via channel.
yaizudamashii commented Jan 19, 2021
Update, I’m encountering this issue with Android API level 30, on fully Flutter app (not add-to-app)
moodstubos commented Feb 4, 2021 •
Update, I’m encountering this issue with Android API level 30, on fully Flutter app (not add-to-app)
same here.
I was already on permission_handler 5.x for some time. Today a pub upgrade brakes my storage permission status (always undetermined although it is granted).
logcat says:
No permissions found in manifest for: 15
(15 is the enum for storage group)
of cause permission is defined in manifest.
I tried to downgrade back to an old 5.x version but no success. Now I am using
permission_handler: 4.4.0+hotfix.4
and it works again (with PermissionHandler().checkPermissionStatus(..) )
edit: only testet on android 11
RomanKapshuk commented Feb 4, 2021
I was already on permission_handler 5.x for some time. Today a pub upgrade breaks my storage permission status
Same issue here. Please, fix this bug asap
claudiowagner commented Feb 4, 2021 •
Same issue here.
Something is wrong with the «platform_interface» project in version 2.0.2 .
I put this in my pubspec.yaml and worked:
mvanbeusekom commented Feb 4, 2021
@moodstubos, @RomanKapshuk, @claudiowagner, a fix is on its way should be uploaded in 30 minutes.
mvanbeusekom commented Feb 4, 2021
@moodstubos, @RomanKapshuk, @claudiowagner, I have just released hotfix 5.1.0+2 which should fix this problem. Someone from the community added a new permission to iOS and updated the constants but forgot to do the same on Android. I also completely overlooked it, causing this problem.
moodstubos commented Feb 4, 2021 •
@mvanbeusekom thanks a lot for your explanation. I will try the fix.
Edit: Update to 5.1.0+2 fixed the issue. Thanks again!
yaizudamashii commented Feb 5, 2021 •
@moodstubos Hmm I tried 5.1.0+2 but I’m still seeing the same issue. Are you using flutter channel stable ?
Edit: also checked on channel beta but no luck.
Источник