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

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

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

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

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

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

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

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

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

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

  var file = e.target.files[0];
  if (!/.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
    this.$refs.alertDlg.show(this.tags.invalidImg);
    return false
  }
  var reader = new FileReader()
  reader.onload = (e) => {
    var data
    if (typeof e.target.result === 'object') {
      // 把Array Buffer转化为blob 如果是base64不需要
      data = window.URL.createObjectURL(new Blob([e.target.result]))
    } else {
      data = e.target.result
    }
    this.logoOpts.img = data
	this.loading=false;
  }
  // reader.readAsDataURL(file)// 转化为base64
  reader.readAsArrayBuffer(file)// 转化为blob

原文地址:https://blog.csdn.net/flyinmind/article/details/130194217

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_24570.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注