I'm creating a project in .Net MAUI that takes photos and I would like to know how can I save it in a gallery by creating a folder.
I've seen that Google has changed its permissions.
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<!-- Required only if your app needs to access images or photos that other apps created -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<!-- Required only if your app needs to access videos that other apps created -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
This is the code:
string sGpath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
// Crear la ruta completa del archivo
var folderPath = Path.Combine(sGpath, "GPV2");
photo.FileName = $ "{vf.IdVisita}_{DateTime.Now:yy_MM_dd_HH_mm_ss}.jpg";
string uniqueFileName = $ "{vf.IdVisita}_{DateTime.Now:yy_MM_dd_HH_mm_ss}.jpg";
string filePath = Path.Combine(folderPath, photo.FileName);
if (!Directory.Exists(folderPath)) {
Directory.CreateDirectory(folderPath);
}
using Stream sourceStream = await photo.OpenReadAsync();
Console.WriteLine($ "Archivo guardado en {filePath}");
vf.Titulo = uniqueFileName;
using(FileStream fileStream = File.OpenRead(filePath)) {
vf.Foto = ReadFully(fileStream);
}
The path in which it is saved for me is
/data/user/0/com.companyname.photov2/files/Pictures/GPV2/1_24_05_30_10_53_48.jpg
Even with that it doesn't keep me in gallery, how can I do it?
You can use the following code to save the image stream to gallery of your android device.
public static class ImageSaveHelper
{
public static async Task SaveImage(Stream imageStream)
{
using var stream = imageStream;
using var memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
stream.Position = 0;
memoryStream.Position = 0;
#if ANDROID
var context = Platform.CurrentActivity;
if (OperatingSystem.IsAndroidVersionAtLeast(29))
{
Android.Content.ContentResolver resolver = context.ContentResolver;
Android.Content.ContentValues contentValues = new();
contentValues.Put(Android.Provider.MediaStore.IMediaColumns.DisplayName, "image.png");
contentValues.Put(Android.Provider.MediaStore.IMediaColumns.MimeType, "image/png");
contentValues.Put(Android.Provider.MediaStore.IMediaColumns.RelativePath, "DCIM/" + "image");
Android.Net.Uri imageUri = resolver.Insert(Android.Provider.MediaStore.Images.Media.ExternalContentUri, contentValues);
var os = resolver.OpenOutputStream(imageUri);
Android.Graphics.BitmapFactory.Options options = new();
options.InJustDecodeBounds = true;
var bitmap = Android.Graphics.BitmapFactory.DecodeStream(stream);
bitmap.Compress(Android.Graphics.Bitmap.CompressFormat.Png, 100, os);
os.Flush();
os.Close();
}
else
{
Java.IO.File storagePath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures);
string path = System.IO.Path.Combine(storagePath.ToString(), "image.png");
System.IO.File.WriteAllBytes(path, memoryStream.ToArray());
var mediaScanIntent = new Android.Content.Intent(Android.Content.Intent.ActionMediaScannerScanFile);
mediaScanIntent.SetData(Android.Net.Uri.FromFile(new Java.IO.File(path)));
context.SendBroadcast(mediaScanIntent);
}
#endif
}
}
Note:
How Can I request storage acces ? with Permissions.CheckStatusAsync<Permissions.Media>()? This doesn't work
You need to add the following permissions if you want to save and read image to Gallery not Permissions.Media
.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
From document Permissions, we know that permission Permissions.Media
will always return Granted when checked or requested.
And you also need the following api on the maui:
PermissionStatus statusread = await Permissions.RequestAsync<Permissions.StorageRead>();
PermissionStatus statuswrite = await Permissions.RequestAsync<Permissions.StorageWrite>();