HybridWebView - Обрабатывать файл типа ввода - PullRequest
0 голосов
/ 24 октября 2019

Я не могу найти правильный способ обработки файла типа ввода, который присутствует на странице, отображаемой в HybridWebView;Мне нужно справиться с этим в Android и iOS;Я много чего перепробовал, но не могу найти правильный путь.

Контекст

При запуске приложения отображается полная страница HybridWebView, когда я нажимаю на файл типа ввода, ничегослучается.

В качестве второго шага, очевидно, если присутствуют multiple или accept атрибуты 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;
    }
}

Ответы [ 2 ]

0 голосов
/ 26 октября 2019

Наконец, у меня есть работающий 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;
    }
}
0 голосов
/ 25 октября 2019

Вы можете попробовать это, посмотрите, работает ли оно:

в вашем 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;
        }
...