Search code examples
c#xamarin.androidfilechooser

How to implement open file chooser for Android 5.0 above in Xamarin?


I am using below code for opening file chooser, I am not sure how to implement it for Android 5.0 and above.

Action<IValueCallback, Java.Lang.String, Java.Lang.String> callback;

public FileChooserWebChromeClient(Action<IValueCallback, Java.Lang.String, Java.Lang.String> callback)
{
    this.callback = callback;
}       

//For Android 4.1
[Java.Interop.Export]
public void openFileChooser(IValueCallback uploadMsg, Java.Lang.String acceptType, Java.Lang.String capture)
{
    callback(uploadMsg, acceptType, capture);
}

// For Android > 5.0
//I am stuck here, taken from Android
[Java.Interop.Export]
public bool onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)
{
    mUploadCallbackLollipop = filePathCallback;
    openFileChooserActivity();
    return true;
}

Callback function:

var chrome = new FileChooserWebChromeClient((uploadMsg, acceptType, capture) =>
{
    MainActivity.UploadMessage = uploadMsg;
    if(Build.VERSION.SdkInt < BuildVersionCodes.Kitkat)
    {
        var i = new Intent(Intent.ActionGetContent);

        //To set all type of files
        i.SetType("image/*");

        //Here File Chooser dialog is started as Activity, and it gives result while coming back from that Activity.
        ((MainActivity)this.Context).StartActivityForResult(Intent.CreateChooser(i, "File Chooser"), MainActivity.GALLERY_INTENT_CALLED);
    }
    else
    {
        var i = new Intent(Intent.ActionOpenDocument);
        i.AddCategory(Intent.CategoryOpenable);

        //To set all type of files
        i.SetType("image/*");

        //Here File Chooser dialog is started as Activity, and it gives result while coming back from that Activity.
        ((MainActivity)this.Context).StartActivityForResult(Intent.CreateChooser(i, "File Chooser"), MainActivity.GALLERY_KITKAT_INTENT_CALLED);
    }             
});

How to implement callback for Android 5.0 above, please someone help me


Solution

  • Following code opening file chooser in WebView for Android 5.0 (Lollipop)

    // For Android > 5.0
            [Android.Runtime.Register("onShowFileChooser", "(Landroid/webkit/WebView;Landroid/webkit/ValueCallback;Landroid/webkit/WebChromeClient$FileChooserParams;)Z", "GetOnShowFileChooser_Landroid_webkit_WebView_Landroid_webkit_ValueCallback_Landroid_webkit_WebChromeClient_FileChooserParams_Handler")]
            public override Boolean OnShowFileChooser (Android.Webkit.WebView webView, IValueCallback uploadMsg, WebChromeClient.FileChooserParams fileChooserParams)
            {
                try
                {
                    callback(uploadMsg, null, null);
                }
                catch(Exception e)
                {
    
                }
                return true;
            }
    

    Callback can be implemented same as in other versions, but path can't be passed directly in OnReceiveValue method. It should be passed as below:

    UploadMessage.OnReceiveValue(WebChromeClient.FileChooserParams.ParseResult(Convert.ToInt32(resultCode), intent));
    

    I was getting type cast exception while using below function which I used for older versions.

    UploadMessage.OnReceiveValue(Android.Net.Uri.Parse(string.Format("file://{0}", result.ToString())));
    

    Reference:

    From Xamarin Documentation

    And from Android Source:

    https://github.com/anthonycr/Lightning-Browser/issues/253