permission denied to access media from storage in multi image picker - flutter

i am uploading images from gallery to app, my app ask for permission automatically but dont know what happen now it is not asking for the permission and getting error "permission denied " when i try to open gallery in the app
loadGallery() async {
List<Asset> resultImages = List<Asset>();
try {
resultImages = await MultiImagePicker.pickImages(
maxImages: 10,
selectedAssets: images,
);
} catch (e) {
print("error is : $e");
}
setState(() {
images = resultImages;
});
}

In your AndroidManifest.xml file located in android/app/src/main, include these lines,
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
under the "<manifest.." tag.

There can be many scenarios that can be in the picture.
1) Maybe you have clicked on the permission for never option, where it does not asks permission later.
you have to check if you have the permission for accessing I have written the code check it just wrote an example, modify accordingly
check out the below Code for asking the permission
Future<bool> checkAndRequestCameraPermissions() async {
PermissionStatus permission =
await PermissionHandler().checkPermissionStatus(PermissionGroup.camera);
if (permission != PermissionStatus.granted) {
Map<PermissionGroup, PermissionStatus> permissions =
await PermissionHandler().requestPermissions([PermissionGroup.camera]);
return permissions[PermissionGroup.camera] == PermissionStatus.granted;
} else {
return true;
}
}
later only check if you have permission then do the required process.
if (await checkAndRequestCameraPermissions()) {
File image = await ImagePicker.pickImage(source: ImageSource.camera);
// continue with the image ...
}
for time being i have used the image_picker you can use Multi Image Picker.
check out the code and let me know.
Thanks.

Try to change the version of multi image picker it will work.. if you are using latest version and still received same problem then change it to old version.

Related

Permissions always returns "Granted" for Permissions.Photos in .net MAUI

I am using below code to access gallery permissions in .net maui but it always returns Granted even on first time launch of the application and I am not able to see the permission popup saying "This app would like to access photos and media on your device"
public static async Task<PermissionStatus> GetMediaPermissionStatus()
{
PermissionStatus mediaResult = PermissionStatus.Disabled;
var tcs = new TaskCompletionSource<PermissionStatus>();
var status = await Permissions.CheckStatusAsync<Permissions.Photos>();
if (status != PermissionStatus.Granted)
{
status = await Permissions.RequestAsync<Permissions.Photos>();
}
tcs.SetResult(status);
return await tcs.Task;
}
Also when I execute below code getting 2 app permission Popups
1st Popup - "Allow application to take pictures and record video"
2nd Popup - "Allow application to access photos and media on your device?"
public async void TakePhoto()
{
if (MediaPicker.Default.IsCaptureSupported)
{
FileResult photo = await Microsoft.Maui.Media.MediaPicker.Default.CapturePhotoAsync();
if (photo != null)
{
// save the file into local storage
string localFilePath = Path.Combine(FileSystem.CacheDirectory, photo.FileName);
using Stream sourceStream = await photo.OpenReadAsync();
using FileStream localFileStream = File.OpenWrite(localFilePath);
await sourceStream.CopyToAsync(localFileStream);
}
}
}
I don't know if it is a bug or I am doing something wrong.
Any help is appreciated!
You can refer to this doc: Permissions of MAUI. There is a table in it. It uses ✔️ to indicate that the permission is supported and ❌ to indicate the permission isn't supported or isn't required
If a permission is marked as ❌, it will always return Granted when checked or requested.
Granted:
The user granted permission or is automatically granted.
Wish it can help you.

Flutter permission_handler : request location permission on iOS

I want to ask user to enable permission only if he denied the permission or the permission is not allowed
This function is working very well on android
Future _getLocationPermission() async {
if (await Permission.location.request().isGranted) {
permissionGranted = true;
} else if (await Permission.location.request().isPermanentlyDenied) {
throw('location.request().isPermanentlyDenied');
} else if (await Permission.location.request().isDenied) {
throw('location.request().isDenied');
permissionGranted = false;
}
}
but on iOS it throw exception permission isPermanentlyDenied
Unhandled Exception: location.request().isPermanentlyDenied
even if the user allowed location permission while using app
I'm using permission_handler package
iOS is stricter, it does not allow you to request for permission if the user has already permanently denied it. In this case your only option is to inform the user about this, and offer the possibility to open application settings and grant permission there. This will likely restart your application if the user grants.
So check the status without requesting:
final status = await Permission.location.status;
If status is permanently denied, display a Flutter dialog (you can't use the system permission grant dialog in this case):
if (status == PermissionStatus.permanentlyDenied) {
// display a dialog, explain the user that he/she can grant
// permission only in the phone's application settings
}
If the user want's to do it, you can route to the application settings:
openAppSettings(); // this is a method of the permission handler package
This method is a future, but in my experience you don't need to await it.
This is just a function that returns bool if the user enables location
or not simple
Future<bool> canGetLocation(Location location) async {
if (!await location.requestService()) return false;
final status = await location.requestPermission();
final granted = PermissionStatus.granted;
final grantedLimited = PermissionStatus.grantedLimited;
bool result = status == granted || status == granted;
return result;
}
if (await canGetLocation(location)) {
// Do something
} else {
final status = await handler.Permission.location.status;
if (status.isPermanentlyDenied || status.isDenied) {
// ask the user to open the app setting
// from permission handler package you have
openAppSettings();
} else {
// show info dialog or something that the user need to enable location services
}
}
Please check this link. You must have to mention permission in POD file also.

Not able to access storage even if storage permission is granted in flutter

I'm using the permission_handler package to request permissions on Android. A user is able to download a file to the downloads folder when he clicks on "Allow" in the Permission.storage popup. (We are calling it Permission.storage when the user installs the app.)
The issue is that if a user clicks on "Don't allow" the first time and "Allow" the second time in other flows in the app, we are still getting a permission denied error and the user is not able to download files like above flow. I've logged and checked the value of the status; it is coming as PermissionStatus.granted only which is expected. Any ideas on how to fix this?
Below is the error log
I/flutter ( 8170): could not download file FileSystemException: Cannot open file, path = '/storage/emulated/0/Download/codes.txt' (OS Error: Permission denied, errno = 13)
/// Permission snippet of first time
final permission =
GetPlatform.isAndroid ? Permission.storage : Permission.photos;
final status = await permission.status;
if (status != PermissionStatus.granted) {
await permission.request().isGranted;
}
/// Snippet when user clicks on download second time
final permission = Permission.storage;
final status = await permission.status;
debugPrint('>>>Status $status'); /// here it is coming as PermissionStatus.granted
if (status != PermissionStatus.granted) {
await permission.request().isGranted;
debugPrint('>>> ${await permission.status}');
}
directory = Directory('/storage/emulated/0/Download');
///perform other stuff to download file
when permission_handler package send request to user with request() function, we made in await so after close dialog you check second time if permission granted or not and if permission granted then perform other stuff to download file else you can again send request for the permission.
/// Snippet when user clicks on download second time
final permission = Permission.storage;
final status = await permission.status;
debugPrint('>>>Status $status'); /// here it is coming as PermissionStatus.granted
if (status != PermissionStatus.granted) {
await permission.request();
if(await permission.status.isGranted){
directory = Directory('/storage/emulated/0/Download');
///perform other stuff to download file
} else {
await permission.request();
}
debugPrint('>>> ${await permission.status}');
}
directory = Directory('/storage/emulated/0/Download');
///perform other stuff to download file

Flutter - How to save a file requesting permission with Permission Handler if my code is deprecated?

I'm new to Flutter and I've been following this tutorial but it's from 2020 and I know a lot of things have changed.
I want to save a file on my local phone and apparently I need to ask permission to do so. I'm not sure if checking the platform is still needed or not.
I don't want to run the --no-sound-null-safety command.
This is the only part that I wasn't able to update by myself.
_save() async {
if (Platform.isAndroid) {
await _askPermission();
}
var response = await Dio().get(widget.imgUrl!,
options: Options(responseType: ResponseType.bytes));
final result =
await ImageGallerySaver.saveImage(Uint8List.fromList(response.data));
print(result);
Navigator.pop(context);
}
_askPermission() async {
if (Platform.isIOS) {
await PermissionHandler().requestPermissions([PermissionGroup.photos]);
} else {
await PermissionHandler().checkPermissionStatus(PermissionGroup.storage);
}
}
The _save method seems alright but I wonder if there's something to update there as well.
The _askPermission method is the one that I need help with.

How to record a video with Camera Plugin in flutter?

I have this page where the camera is initialized and ready with a button that will record and stop the video, so I tried this :
FlatButton(
onPressed: () => {
!isRecording
? {
setState(() {
isRecording = true;
}),
cameraController.prepareForVideoRecording(),
cameraController.startVideoRecording('assets/Videos/test.mp4')
}
: cameraController.stopVideoRecording(),
},
............
but throws this error : nhandled Exception: CameraException(videoRecordingFailed, assets/Videos/test.mp4: open failed: ENOENT (No such file or directory)).
I don't understand, I don't want to open this file I want to save it there, Is there sth wrong with my code ?
In the new version, static method startRecordingVideo doesn't take any string parameter.
When you want to start the recording just see whether a video is already getting recorded, if not start
if (!_controller.value.isRecordingVideo) {
_controller.startVideoRecording();
}
and when you want to finish the recording you can call the static method stopVideoRecording() and it will give you a object of the class XFile, it will have the path to your video.
if (_controller.value.isRecordingVideo) {
XFile videoFile = await _controller.stopVideoRecording();
print(videoFile.path);//and there is more in this XFile object
}
This thing has worked for me. I am new to flutter please improve my answer if you know more.
You are trying to save a video in your assets folder which is not possible ,
What you need to do is to save to device locally either common folders like downloads or app directory.
Here is an example of how to go about it
dependencies:
path_provider:
Flutter plugin for getting commonly used locations on host platform
file systems, such as the temp and app data directories.
We will be saving the video to app directory.
We need to get the path to the directory where the file is or will be. Usually a file is put in the application's document directory, in the application's cache directory, or in the external storage directory. To get the path easily and reduce the chance of type, we can use PathProvider
Future<String> _startVideoRecording() async {
if (!controller.value.isInitialized) {
return null;
}
// Do nothing if a recording is on progress
if (controller.value.isRecordingVideo) {
return null;
}
//get storage path
final Directory appDirectory = await getApplicationDocumentsDirectory();
final String videoDirectory = '${appDirectory.path}/Videos';
await Directory(videoDirectory).create(recursive: true);
final String currentTime = DateTime.now().millisecondsSinceEpoch.toString();
final String filePath = '$videoDirectory/${currentTime}.mp4';
try {
await controller.startVideoRecording(filePath);
videoPath = filePath;
} on CameraException catch (e) {
_showCameraException(e);
return null;
}
//gives you path of where the video was stored
return filePath;
}