Android webview点击<input type=“file“>选择文件的实现

时间:2025-03-03 14:27:06

从安卓5.0开始(之前的版本没有测试过,只是从一些资料中得知此信息),webview中<input type="file">的打开文件实现已经改变,点击没有任何反应,需要重载WebChromeClient,处理打开文件的操作。

因为版本不断更新迭代,网上的一些实现中会用到deprecated的函数,以下给出“2023/4”我的实现,里面用到registerForActivityResult。相对于startActivityForResult,它更好一些,它使用回调,使得不用在多个函数中配合实现一个功能。

首先,注册一个ActivityResultLauncher,用于打开文件浏览器选择文件:

//解决安卓5及以上版本html<input type="file">无响应问题
private ValueCallback<Uri[]> checkedFile;
private ActivityResultLauncher<String[]> explorer;

//在中实现以下内容,实现打开文件浏览器选择文件的功能
protected void onCreate(Bundle savedInstanceState) {
    ........
    explorer = registerForActivityResult(new (),
	result -> {
		("Open file `{}`", result);
		if(checkedFile != null) {
			if(result == null) {
				(null); //result没选择时为null
			} else {
				(new Uri[]{result});
			}
			checkedFile = null;
		}
	});
    ........
}

其次,安卓5或以上版本,重载(老版本需要重载其他函数,可以参照网上其他介绍,我认为5以下没必要兼容了,所以不实现)。

WebChromeClient chromeClient = new WebChromeClient() {
	@Override
	public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,  fileChooserParams) {
		if (checkedFile != null) {
			//防止上一次没选文件,直接退出的情况,导致后面选择无法正常工作
			(null);
		}
		checkedFile = filePathCallback;
		String[] acceptTypes = ();
		("fileChooserParams:{},sdk_int:{}", (acceptTypes).toArray(), .SDK_INT);
		if(.SDK_INT <= Build.VERSION_CODES.N){
			(new String[]{"*/*"});
		} else {
			(acceptTypes);
		}
		return true;
	}
};
........
//设置到webview中
(chromeClient);

注意,代码中判断了安卓7及以前版本,不能使用fileChooserParams参数来限制选择的文件类型,否则点击没有响应,也无错误信息,原因未知,所以这里传"*/*"。

一个关键点:在onShowFileChooser中获得checkedFile,这是一个回调。在explorer选中文件后,调用将结果传递给webview。

在html中的处理与普通web浏览器完全相同,以下是获取图片文件并裁剪的例子,完整内容见此连接serverui/file/settings/ · master · 至简网格 / 至简网格企业服务 · GitCode,在startCropLogo函数中。

  var file = [0];
  if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test()) {
    this.$();
    return false
  }
  var reader = new FileReader()
   = (e) => {
    var data
    if (typeof  === 'object') {
      // 把Array Buffer转化为blob 如果是base64不需要
      data = (new Blob([]))
    } else {
      data = 
    }
     = data
	=false;
  }
  // (file)// 转化为base64
  (file)// 转化为blob

相关文章