我找不到处理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;
}
}
您可以尝试一下,看看是否有效:
在您的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;
}
最后,我有了一个带有输入类型文件的可运行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;
}
}