MAUI file picker returns a cached file address on android platform

alireza mirabedini 0 Reputation points
2023-07-17T11:58:09.94+00:00

I use FilePicker to pick address of files that user selected but in android it seems copy the user selected files to cache folder and returns that copied files address.

 private async void bExecute_Clicked(object sender, EventArgs e)
    {
        FilePickerFileType customFileType = new FilePickerFileType(
        new Dictionary<DevicePlatform, IEnumerable<string>>
        {
                        { DevicePlatform.iOS, new[] { "public.audio" } }, // UTType values
                        { DevicePlatform.Android, new[] { "audio/*" } }, // MIME type
                        { DevicePlatform.WinUI, new[] { ".mp3", ".wav", ".wma", ".m4a", ".flac" } }, // file extension
                        { DevicePlatform.Tizen, new[] { "*/*" } },
                        { DevicePlatform.macOS, new[] { ".mp3", ".wav", ".wma", ".m4a", ".flac" } }, // UTType values
        });
        PickOptions options = new()
        {
            PickerTitle = "Please select audio file's",
            FileTypes = customFileType
        };

        var fileResult = await FilePicker.Default.PickMultipleAsync(options);

        // Let user pick files (and handling cancelling)
        foreach (FileResult file in fileResult)
        {
            var tfile = TagLib.File.Create(file.FullPath);
                  ...
        }
    }

it returns something like this on android User's image

but in windows it works normally.

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,648 questions
.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,231 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,648 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 72,251 Reputation points Microsoft Vendor
    2023-07-25T00:48:54.3233333+00:00

    Hello,

    You can use ContentResolver to update the audio file by audio id. UpdateAlbumInformation(1000000037, "TestAudio");

    public void UpdatedisplayNameInformation(long audioId, string displayName)
        {
           ContentResolver contentResolver = Microsoft.Maui.ApplicationModel.Platform.CurrentActivity.ContentResolver;     
                // Create the content values object to hold the new display name information
                ContentValues values = new ContentValues();
                values.Put(Android.Provider.MediaStore.Audio.Media.InterfaceConsts.DisplayName, displayName);
            // Build the content URI for the specific audio file using its ID
                Android.Net.Uri contentUri = ContentUris.WithAppendedId(Android.Provider.MediaStore.Audio.Media.ExternalContentUri, audioId);
                contentResolver.Update(contentUri, values, null, null);
           
        }
    

    How to get the audio id? You can use MediaStore to get it.

    Firstly, you need to add following permission to your AndroidManifest.xml file.

     <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

    Then, you need to check the StorageRead permission, if this permission is granted, you can use Mediastore to get all of the audio file, I tested file type is .mp3, So I set MIME type to "audio/mpeg", you can use Cursor to get audio ID like following code.

    PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.StorageRead>();
           
            if (status == PermissionStatus.Granted)
            {          
                var projection = new List<string>()
                    {
                        Android.Provider.MediaStore.Audio.Media.InterfaceConsts.Id,
                        Android.Provider.MediaStore.Audio.Media.InterfaceConsts.DisplayName,
                       Android.Provider.MediaStore.Audio.Media.InterfaceConsts.DateAdded,
                      Android.Provider.MediaStore.Audio.Media.InterfaceConsts.Title,
                       Android.Provider.MediaStore.Audio.Media.InterfaceConsts.RelativePath,
                      Android.Provider.MediaStore.Audio.Media.InterfaceConsts.MimeType
                    }.ToArray();
    
    
    
    
    
               string selection = Android.Provider.MediaStore.Audio.Media.InterfaceConsts.MimeType + " = ?";
    
               var selectionArgs = new List<string>()
                {
                        "audio/mpeg"
                };
    
               ContentResolver contentResolver = Microsoft.Maui.ApplicationModel.Platform.CurrentActivity.ContentResolver;
                ICursor cursor = contentResolver.Query(Android.Provider.MediaStore.Audio.Media.ExternalContentUri, projection, selection, selectionArgs.ToArray(), null);
                if (cursor != null && cursor.Count > 0)
                {
                    int idColumn = cursor.GetColumnIndexOrThrow(Android.Provider.MediaStore.Audio.Media.InterfaceConsts.Id);
                    int dispNameColumn = cursor.GetColumnIndexOrThrow(Android.Provider.MediaStore.Audio.Media.InterfaceConsts.DisplayName);
                    cursor.MoveToFirst();
    
    
    
    
                   do
                    {
                        //1000000034
                        long id = cursor.GetLong(idColumn);
                        string displayName = cursor.GetString(dispNameColumn);
                        Android.Net.Uri uri1 = Android.Provider.MediaStore.Audio.Media.ExternalContentUri.BuildUpon().AppendPath(id.ToString()).Build();
                        //"content://media/external/audio/media/1000000037"
                        string androidUri = uri1.ToString();
                        long androidFileId = id;
                        break;
    
                   }
                    while (cursor.MoveToNext());
                   cursor.Close();
                    cursor.Dispose();
                }
            }
            else
            {
                PermissionStatus RequestStatus = await Permissions.RequestAsync<Permissions.StorageRead>();
            }
    

    Best Regards,

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    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 comments No comments