0
votes

I am using following code to pick a file using FilePicker in xamarin forms. End goal is to give Android Uri to a service in Xamarin.Android project, the service transfers the file to somewhere.

How do I get Android Uri(Android.Net.Uri )from FilePicker result in xamarin forms? Android service only accepts Android.Net.Uri type.

try
        {
            var result = await FilePicker.PickAsync(new PickOptions { 
            
                PickerTitle = "Select zip file"
            });
          
            if (result != null)
            {
                FileNameLabel.Text = $"File Name: {result.FileName}";
                if (!result.FileName.EndsWith("zip", StringComparison.OrdinalIgnoreCase))
                {
                   await DisplayAlert("Wrong File", "Selected file is not right", "Ok");
                }
               
            }
        }
        catch (Exception ex)
        {
            // The user canceled or something went wrong
        }

I tried the following:

firmwareFullPath = result.FullPath;
Android.Net.Uri FirmwareUri = Android.Net.Uri.Parse(firmwareFullPath);

But the service gives file not found error. The service works fine in Xamarin.Android project with the same file with native file picker activity where I get the Uri from intent returned after file selection. Below is the comparison on Uri objects, one object generated using :

Android.Net.Uri.Parse(firmwareFullPath);

The other from

 protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, data);
            if ((resultCode == Result.Ok) && (data != null))
            {
                Android.Net.Uri FirmwareUri = data.Data;

            }
        
    }

Uri Object from Xamarin.Form FilePicker enter image description here

Uri Object from Xamarin.Andriod enter image description here

**Major difference is Authority and EncodedAuthority are null in case of xamarin forms filepicker **

2

2 Answers

0
votes

The easiest way would be to use the path of this and create URI,

I am not sure what the response of PickAsync is but if I am not wrong you should be getting a Path.

var filePath = result.Path;

Now to convert this to Android URI just pass in the path as Parameter and you're done

var fileUri = Android.Net.Uri.Parse(filePath);

Goodluck!

Feel free to get back if you have queries

0
votes

About getting picker uri file path in Forms and Android, I do one sample that you can take a look.

In Forms, using dependencyservice to get uri path.

Creating interface in Forms:

public  interface IFileChanged
{
    object filepath(string path);
}

In Android, to implement this interface:

[assembly: Dependency(typeof(FileChanged))]

namespace demo3.Droid {
class FileChanged : IFileChanged { Android.Net.Uri uri;

    object IFileChanged.filepath(string path)
    {
        Java.IO.File file = new Java.IO.File(path);
        uri = Android.Net.Uri.FromFile(file);
        return uri;
    }
}}

private async void btn3_Clicked(object sender, EventArgs e)
    {
        var file = await CrossFilePicker.Current.PickFile();
        string path = file.FilePath;
        var fileuri = DependencyService.Get<IFileChanged>().filepath(path);
       
    }

The path like {file:///storage/emulated/0/Download/a5.jpg}

If you get picker file path in Android, the path like /document/raw:/storage/emulated/0/Download/a5.jpg, but it is the same file.

private void Filepicker_Click(object sender, System.EventArgs e)
    {
        Intent intent = new Intent(Intent.ActionGetContent);
        intent.SetType("*/*");
      
        try
        {
            StartActivityForResult(Intent.CreateChooser(intent, "Select a file"), 0);
        }
        catch (System.Exception exAct)
        {
            System.Diagnostics.Debug.Write(exAct);
        }

    }
    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, data);
        if ((resultCode == Result.Ok) && (data != null))
        {
            Android.Net.Uri FirmwareUri = data.Data;
            string path = FirmwareUri.Path;
        }

    }