我目前正在使用 Xamarin 构建跨平台移动应用程序。
基本上我的应用程序仅使用网络视图(网络视图仅打开具有上传图像功能的网站),对于某些提取功能我必须使用适用于Android的webchromeclient。
添加设置webchromeclient后,webview无法从Android设备打开文件选择器。 (iphone 工作正常,因为 webchromeclient 与 IOS 路径无关);
这是我的项目的结构
---test
|_ CustomWebView.cs
|_ MainPage.xaml
|_ MainPage.cs
---test.Android
|_ MainActivity.cs
|_ AndroidCustomWebViewRenderer.cs
---test.IOS
|_ IOS files
自定义WebView.cs
using Xamarin.Forms;
namespace test
{
public class CustomWebView : WebView
{
}
}
AndroidCustomWebViewRenderer.cs
[assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebViewRenderer))]
public class CustomWebViewRenderer : WebViewRenderer
{
public CustomWebViewRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
if (this.Control != null)
{
Android.Webkit.WebView webView = this.Control;
webView.Settings.SetGeolocationEnabled(true);
webView.Settings.JavaScriptEnabled = true;
webView.Settings.AllowFileAccess = true;
webView.Settings.AllowFileAccessFromFileURLs = true;
webView.Settings.AllowUniversalAccessFromFileURLs = true;
webView.SetWebChromeClient(new TestWebViewClient());
}
}
public class TestWebViewClient : Android.Webkit.WebChromeClient
{
public override bool OnShowFileChooser(Android.Webkit.WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
{
return base.OnShowFileChooser(webView, filePathCallback, fileChooserParams);
}
public override bool OnConsoleMessage(Android.Webkit.ConsoleMessage consoleMessage)
{
Log.Debug("WebViewConsole", $"{consoleMessage.Message()}");
return base.OnConsoleMessage(consoleMessage);
}
}
}
MainActivity.cs
namespace test.Droid
{
[Activity(Label = "test", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize )]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
AndroidManifest.xml拥有访问Storage的所有权限。 所以我认为 webchromeclient 有问题,缺少从 android 打开默认文件选择器的东西。
您可以尝试在TestWebViewClient中添加以下代码:
public class TestWebViewClient : Android.Webkit.WebChromeClient
{
public static int filechooser = 1;
public static IValueCallback message;
public override bool OnShowFileChooser(global::Android.Webkit.WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
{
message = filePathCallback;
Intent chooserIntent = new Intent(Intent.ActionGetContent);
chooserIntent.AddCategory(Intent.CategoryOpenable);
chooserIntent.SetType("*/*");
Xamarin.Essentials.Platform.Platform.CurrentActivity.StartActivityForResult(Intent.CreateChooser(chooserIntent, "File Chooser"), filechooser);
return true;
}
}
在主活动中:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if(data !=null)
{
if (requestCode == MyWebChromeClient.filechooser)
{
if(MyWebChromeClient.message !=null)
{
TestWebViewClient.message.OnReceiveValue(WebChromeClient.FileChooserParams.ParseResult((int)resultCode, data));
TestWebViewClient.message = null;
}
}
}
}