如何在 Xamarin 中为 Android 5.0 以上版本实现打开文件选择器?

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

我正在使用下面的代码打开文件选择器,我不确定如何为 Android 5.0 及更高版本实现它。

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;
}

回调函数:

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);
    }             
});

如何实现Android5.0以上的回调,求大神帮忙

以下代码在 WebView 中为 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;
        }

回调可以和其他版本一样实现,但是OnReceiveValue方法中不能直接传路径。它应该按如下方式传递:

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

我在使用以下用于旧版本的函数时出现类型转换异常。

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

参考:

From Xamarin Documentation

来自Android来源:

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

第一步= 文件上传可以,我们需要在 android 清单中授予读/写权限。 在主要 Activity.cs

step2=
private Action<int, Result, Intent> resultCallbackvalue;

public void StartActivity(Intent intent, int requestCode, Action<int, Result, Intent> resultCallback)
{
this.resultCallbackvalue = resultCallback;
StartActivityForResult(intent, requestCode);
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (this.resultCallbackvalue != null)
{
this.resultCallbackvalue(requestCode, resultCode, data);
this.resultCallbackvalue = null;
}
}
step3= add ExtendedChromeClient,cs Inheriting from : WebChromeClient

private static int filechooser = 1;
private IValueCallback message;
private MainActivity activity = null;

  public ExtendedChromeClient(MainActivity context)
    {
        this.activity = context;
    }

  public override bool OnShowFileChooser(WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
    {
        this.message = filePathCallback;
        Intent chooserIntent = fileChooserParams.CreateIntent();
        chooserIntent.AddCategory(Intent.CategoryOpenable);
        this.activity.StartActivity(Intent.CreateChooser(chooserIntent, "File Chooser"), filechooser, this.OnActivityResult);
        return true;
    }

  private void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        if (data != null)
        {
            if (requestCode == filechooser)
            {
                if (null == this.message)
                {
                    return;
                }

                this.message.OnReceiveValue(WebChromeClient.FileChooserParams.ParseResult((int)resultCode, data));
                this.message = null;
            }
        }
    }