HybridWebView-处理输入类型文件

问题描述 投票:0回答:2

我找不到处理HybridWebView显示页面中存在的输入类型文件的正确方法;我需要在Android和iOS中处理它;我尝试了很多事情,但找不到正确的方法。

上下文

当应用程序启动时显示一个完整的页面HybridWebView,当我点击输入类型文件时,什么也没有发生。

显然,第二步,如果存在multipleaccept HTML5属性,我必须正确处理它们,例如。我必须从控件或类似内容中读取它们。

代码

HybridWebViewRenderer事件中OnElementChanged中的当前代码如下:

var chromeClient = new CusWebChromeClient((uploadMsg, acceptType, capture) => {
    MainActivity.UploadMessage = uploadMsg;

    var i = new Intent(Intent.ActionGetContent);
    i.AddCategory(Intent.CategoryOpenable);
    i.SetType("*/*");

    var chooserIntent = Intent.CreateChooser(i, "Choose file");
    //chooserIntent.PutExtra(Intent.ExtraInitialIntents, new Intent[] { captureIntent });

    ((Activity)_context).StartActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
});

webView.SetWebChromeClient(chromeClient);

这里是Android MainActivity.cs:

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    public static IValueCallback UploadMessage;
    private static int FILECHOOSER_RESULTCODE = 1;
    public static Android.Net.Uri mCapturedImageURI;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        WebView.SetWebContentsDebuggingEnabled(true);

        base.OnCreate(savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        LoadApplication(new App());
    }

    protected override void OnActivityResult(int requestCode, Result resultCode, Android.Content.Intent data)
    {
        if (requestCode == FILECHOOSER_RESULTCODE)
        {
            if (null == UploadMessage)
                return;
            Java.Lang.Object result = data == null ? mCapturedImageURI : data.Data;

            UploadMessage.OnReceiveValue(new Android.Net.Uri[] { (Android.Net.Uri)result });
            UploadMessage = null;
        }
        else
            base.OnActivityResult(requestCode, resultCode, data);
    }
}

这里是CusWebChromeClient

public class CusWebChromeClient : global::Android.Webkit.WebChromeClient
{
    private Action<IValueCallback, Java.Lang.String, Java.Lang.String> callback;

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

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

    // For Android > 5.0
    public override Boolean OnShowFileChooser(Android.Webkit.WebView webView, IValueCallback uploadMsg, WebChromeClient.FileChooserParams fileChooserParams)
    {
        try
        {
            callback(uploadMsg, null, null);
        }
        catch (Exception)
        {

        }
        return true;
    }
}
xamarin xamarin.forms xamarin.android xamarin.ios
2个回答
0
投票

您可以尝试一下,看看是否有效:

在您的MainActivity中添加此:

private Action<int, Result, Intent> _resultCallback;
public static MainActivity Instance;

protected override void OnCreate(Bundle savedInstanceState)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;
        base.OnCreate(savedInstanceState);
        Instance = this;
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        LoadApplication(new App());
    }
public void StartActivity(Intent intent, int requestCode, Action<int, Result, Intent> resultCallback)
 {
   _resultCallback = resultCallback;
   StartActivityForResult(intent, requestCode);
 }
protected override void OnActivityResult (int requestCode, Result resultCode, Intent data)
 {
    base.OnActivityResult (requestCode, resultCode, data);
    if (_resultCallback != null)
     {
       _resultCallback(requestCode, resultCode, data);
       _resultCallback = null;
     }
}

在您的CusWebChromeClient中添加此:

private void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            if (data != null)
            {
                if (requestCode == FILECHOOSER_RESULTCODE) 
                {
                    if (null == mUploadMessage || data == null)
                        return;
                    mUploadMessage.OnReceiveValue (WebChromeClient.FileChooserParams.ParseResult((int)resultCode, data));
                    mUploadMessage = null;
                }
            }
        }

[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 bool OnShowFileChooser (Android.Webkit.WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
        {

            mUploadMessage = filePathCallback;
            Intent i = new Intent(Intent.ActionGetContent);
            i.AddCategory(Intent.CategoryOpenable);
            i.SetType("image/*");
            Intent chooserIntent = Intent.CreateChooser(i,"File Browser");
            MainActivity.Instance.StartActivity(chooserIntent, FILECHOOSER_RESULTCODE, OnActivityResult);
            //return base.OnShowFileChooser (webView, filePathCallback, fileChooserParams);
            return true;
        }

0
投票

最后,我有了一个带有输入类型文件的可运行HybridWebView!

在MainActivity中:

internal static int FILECHOOSER_RESULTCODE = 1;

protected override void OnActivityResult(int requestCode, Result resultCode, Intent intent)
{
    // Handles the response from the FileChooser
    if (requestCode == FILECHOOSER_RESULTCODE)
    {
        if (null == UploadMessage)
            return;
        Java.Lang.Object result = intent == null || resultCode != Result.Ok
            ? null
            : intent.Data;
        UploadMessage.OnReceiveValue(new Android.Net.Uri[] { (Android.Net.Uri)result });
        UploadMessage = null;
    }
    else
    {
        base.OnActivityResult(requestCode, resultCode, intent);
    }
}

在HybridWebVievRender中:

    Control.SetWebChromeClient(new CusWebChromeClient((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("*/*");

            //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.FILECHOOSER_RESULTCODE);
        }
        else
        {
            var i = new Intent(Intent.ActionOpenDocument);
            i.AddCategory(Intent.CategoryOpenable);

            //To set all image file types. You can change to whatever you need
            i.SetType("*/*");

            //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.FILECHOOSER_RESULTCODE);
        }
    }));

在CusWebChromeClient中:

public class CusWebChromeClient : WebChromeClient
{
    Action<IValueCallback, Java.Lang.String, Java.Lang.String> callback;

    public SistemiWebChromeClient(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+
    public override bool OnShowFileChooser(WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
    {
        //return base.OnShowFileChooser(webView, filePathCallback, fileChooserParams);
        callback(filePathCallback, null, null);

        return true;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.