You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Xamarin应用中的WebView授予文件浏览权限?

Xamarin WebView 文件选择失效解决方案

这个问题是因为Xamarin的WebView默认没有对接原生平台的文件选择逻辑,需要针对Android和iOS分别做自定义处理:

Android 平台处理

  1. 自定义WebChromeClient,重写OnShowFileChooser方法拦截文件选择请求:
public class CustomWebChromeClient : WebChromeClient
{
    private readonly Activity _activity;
    public static IValueCallback FileCallback;

    public CustomWebChromeClient(Activity activity)
    {
        _activity = activity;
    }

    public override bool OnShowFileChooser(Android.Webkit.WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
    {
        FileCallback = filePathCallback;
        var intent = fileChooserParams.CreateIntent();
        try
        {
            _activity.StartActivityForResult(intent, 100);
        }
        catch (ActivityNotFoundException e)
        {
            FileCallback = null;
            return false;
        }
        return true;
    }
}
  1. 在Activity的OnActivityResult中处理选择结果:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
    if (requestCode == 100)
    {
        if (CustomWebChromeClient.FileCallback == null) return;
        var result = resultCode == Result.Ok ? WebChromeClient.FileChooserParams.ParseResult((int)resultCode, data) : null;
        CustomWebChromeClient.FileCallback.OnReceiveValue(result);
        CustomWebChromeClient.FileCallback = null;
    }
}
  1. 给WebView设置自定义的WebChromeClient:
webView.SetWebChromeClient(new CustomWebChromeClient(this));
  1. 确保在AndroidManifest.xml中添加必要权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

(Android 6.0+还需动态申请权限)

iOS 平台处理

  1. 创建自定义的WKWebViewRenderer,实现IWKUIDelegate接口:
[assembly: ExportRenderer(typeof(WebView), typeof(CustomWebViewRenderer))]
namespace YourNamespace.iOS.Renderers
{
    public class CustomWebViewRenderer : WkWebViewRenderer, IWKUIDelegate
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);
            if (NativeView != null)
            {
                ((WKWebView)NativeView).UIDelegate = this;
            }
        }

        [Export("webView:runOpenPanelWithParameters:initiatedByFrame:completionHandler:")]
        public void RunOpenPanel(WKWebView webView, WKOpenPanelParameters parameters, WKFrameInfo frame, Action<NSUrl[]> completionHandler)
        {
            var picker = new UIImagePickerController();
            picker.SourceType = UIImagePickerControllerSourceType.PhotoLibrary;
            picker.Delegate = new ImagePickerDelegate(completionHandler);
            UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(picker, true, null);
        }
    }

    public class ImagePickerDelegate : UIImagePickerControllerDelegate
    {
        private readonly Action<NSUrl[]> _completionHandler;

        public ImagePickerDelegate(Action<NSUrl[]> completionHandler)
        {
            _completionHandler = completionHandler;
        }

        public override void FinishedPickingMedia(UIImagePickerController picker, NSDictionary info)
        {
            var url = info.ValueForKey(UIImagePickerController.ImageUrl) as NSUrl;
            _completionHandler(new[] { url });
            picker.DismissViewController(true, null);
        }

        public override void Canceled(UIImagePickerController picker)
        {
            _completionHandler(null);
            picker.DismissViewController(true, null);
        }
    }
}
  1. 若需支持多种文件类型(不止图片),可替换UIImagePickerController为UIDocumentPickerViewController实现更全面的文件选择。

内容的提问来源于stack exchange,提问作者KuroCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 02:05:43