How to use SAF to select multiple files from Android devices?

志轩 张 0 Reputation points
2024-01-29T11:17:44.4333333+00:00

I know .NET MAUI has FilePicker.PickMultipleAsync method is used to select multiple files, but there are serious performance issues when using this method for selecting large files (800MB and above) or large numbers of files (collections of over 100 small files). Someone has already raised this issue on Github (link here:https://github.com/dotnet/maui/issues/18199), and I would like to use SAF as a temporary alternative until this issue is resolved. So how should I implement it? If there is code, it would be even better.

Developer technologies | .NET | .NET MAUI
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Yonglun Liu (Shanghai Wicresoft Co,.Ltd.) 50,126 Reputation points Microsoft External Staff
    2024-01-30T03:08:20.4266667+00:00

    Hello,

    In MAUI, you can directly call the native methods of the corresponding platform.

    See the following documentation and a simple example of invoking SAF.

    Step 1. Create a static helper class in the Platfroms/Android folder.

    public static class SAFHelper
    {
        private const int READ_REQUEST_CODE = 42;
        public static void SelectMultiFile()
        {
            var intent = new Intent(Intent.ActionOpenDocument); 
            intent.AddCategory(Intent.CategoryOpenable);
            intent.PutExtra(Intent.ExtraAllowMultiple, true); // Turn on multi-select mode
            intent.SetType("image/*"); //In this example, images are selected.
            intent.AddFlags(ActivityFlags.GrantReadUriPermission);
           
            MainActivity.Instance.StartActivityForResult(intent, READ_REQUEST_CODE);
        }
    }
    

    Step 2. Create a static instance of the MainActivity and call the response method after it is completed.

    public class MainActivity : MauiAppCompatActivity
    {
        public static MainActivity Instance { get; private set; }
    
        protected override void OnCreate(Bundle? savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            Instance = this;
        }
        protected override void OnActivityResult(int requestCode, Result resultCode, Intent? data)
        {
            base.OnActivityResult(requestCode, resultCode, data);
            if ( resultCode == Result.Ok && data != null)
            {
                Uri uri = null;
                ClipData clipData = data.ClipData; //For multi-select mode, ClipData is required to get the URI of the file list
                if (clipData != null)
                {
                    for (int i = 0; i < clipData.ItemCount; i++)
                    {
                        ClipData.Item item = clipData.GetItemAt(i);
                        uri = item.Uri;
                        if (uri != null)
                        {
                            Console.WriteLine(uri.ToString()); //Once you have the URI of the file, you can process it here as you wish.
                        }
                    }
                }
            }
        }
    

    Step 3. Invoke the method in MAUI.

    #if ANDROID
                SAFHelper.SelectMultiFile();
    #endif
    

    Best Regards,

    Alec Liu.


    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

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.