Media Picker can't write true location android and UWP cant view images

gembel_abadi 41 Reputation points
2021-02-17T06:25:36.82+00:00

When I use the media picker to write the location of the photo file, it works but the photo file is redirected to a new cache directory that is created. I tried it on the Android emulator. and for uwp itself, it cannot load photos from the folder even though the location is correct.
how the solution is to:
1.The file location for Android photo files can be read,
2. photo files on uwp can appear in the application.
This is the code I use to write the file location.

private async void PilihFotoSiswa(object sender, EventArgs e)
         {
             var photo = await MediaPicker.PickPhotoAsync();
             if (photo == null)
             {
                return;
             }
             FtSiswa.Text = photo.FullPath.ToString();
             KameraFotos.Source = FtSiswa.Text;
             await DisplayAlert("Foto disimpan di: ", FtSiswa.Text, "OK");
         }

Thank you in advance

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,297 questions
0 comments No comments
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 68,901 Reputation points Microsoft Vendor
    2021-02-17T09:33:35.97+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    Please try to use my code to make a test.

    Here is layout AXML code

       <StackLayout>  
               <Button Text="take" Clicked="Button_Clicked"></Button>  
               <Image x:Name="MyImage" ></Image>  
           </StackLayout>  
    

    Here is layout background code.

       using System;  
       using System.Collections.Generic;  
       using System.ComponentModel;  
       using System.IO;  
       using System.Linq;  
       using System.Text;  
       using System.Threading.Tasks;  
       using Xamarin.Essentials;  
       using Xamarin.Forms;  
         
       namespace App48  
       {  
           public partial class MainPage : ContentPage  
           {  
               string PhotoPath = "";  
               public MainPage()  
               {  
                   InitializeComponent();  
               }  
               async Task TakePhotoAsync()  
               {  
                   try  
                   {  
                       var photo = await MediaPicker.CapturePhotoAsync();  
                       await LoadPhotoAsync(photo);  
                       MyImage.Source = ImageSource.FromFile(PhotoPath);  
                       Console.WriteLine($"CapturePhotoAsync COMPLETED: {PhotoPath}");  
                   }  
                   catch (Exception ex)  
                   {  
                       Console.WriteLine($"CapturePhotoAsync THREW: {ex.Message}");  
                   }  
               }  
         
               async Task LoadPhotoAsync(FileResult photo)  
               {  
                   // canceled  
                   if (photo == null)  
                   {  
                       PhotoPath = null;  
                       return;  
                   }  
                   // save the file into local storage  
                   var newFile = Path.Combine(FileSystem.CacheDirectory, photo.FileName);  
                   using (var stream = await photo.OpenReadAsync())  
                   using (var newStream = File.OpenWrite(newFile))  
                       await stream.CopyToAsync(newStream);  
         
                   PhotoPath = newFile;  
               }  
                
         
               private async void Button_Clicked(object sender, EventArgs e)  
               {  
                 await  TakePhotoAsync();  
         
                   
               }  
           }  
       }  
    

    I make a test with above code, it work normally.

    69049-image.png

    ====================
    Update====================

    If you want to make the image to save the public folder, you should create a dependence service to set the path for different platforms, for example, in android, if you want to store this image to the Download folder, you can create a dependence service in the PCL.

       public interface IExternalStorage  
           {  
               string GetPath();  
           }  
    

    In th android, you can achieve this interface.

       [assembly: Dependency(typeof(AndroidImplementation))]  
       namespace App48.Droid  
       {  
           public class AndroidImplementation : IExternalStorage  
           {  
               public string GetPath()  
               {  
                   Context context = Android.App.Application.Context;  
                   var filePath = context.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures); // Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDocuments).AbsolutePath;  
         
                   string download = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath;  
                   return download;  
               }  
           }  
       }  
    

    Add android:requestLegacyExternalStorage="true" in the <application> tag of AndroidManifest.xml.

    Then change var newFile = Path.Combine(DependencyService.Get<IExternalStorage>().GetPath(), photo.FileName); in the LoadPhotoAsync() method.

    Here is running screenshot.

    69451-image.png

    Best Regards,

    Leon Lu


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful