如何为适配XenForo论坛的Android WebView启用文件上传与图片插入功能
解决方案
核心问题原因:Android WebView默认不会响应网页中<input type="file">标签的点击事件,而XenForo的附件上传、插入图片功能正是基于该标签实现,所以需要手动添加文件选择回调逻辑。
修改步骤
1. 新增成员变量
在MainActivity类的成员变量声明区域添加如下代码:
private ValueCallback<Uri[]> mUploadMessage; private final static int FILE_CHOOSER_RESULT_CODE = 1;
位置参考:和已有的private WebView webview;等同级即可。
2. 给WebView添加文件选择处理逻辑
在初始化WebView的代码块(else分支中webview.setWebViewClient(new WebViewClientDemo());语句之后)添加如下代码:
webview.setWebChromeClient(new WebChromeClient() { @Override public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) { // 动态申请必要权限(适配Android 6.0+) if (checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || checkSelfPermission(android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{ android.Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.CAMERA }, 100); return false; } if (mUploadMessage != null) { mUploadMessage.onReceiveValue(null); } mUploadMessage = filePathCallback; // 拉起系统文件选择器 Intent intent = fileChooserParams.createIntent(); try { startActivityForResult(intent, FILE_CHOOSER_RESULT_CODE); } catch (Exception e) { mUploadMessage = null; return false; } return true; } });
3. 添加文件选择结果回调
在MainActivity类中,和onBackPressed()方法同级的位置添加如下代码:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == FILE_CHOOSER_RESULT_CODE && mUploadMessage != null) { Uri[] result = WebChromeClient.FileChooserParams.parseResult(resultCode, data); mUploadMessage.onReceiveValue(result); mUploadMessage = null; } }
4. 适配动态权限申请结果(可选,推荐添加)
同样在MainActivity类中添加如下方法,处理权限申请通过后的逻辑:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 100) { boolean allGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allGranted = false; break; } } if (allGranted) { // 权限通过后重新触发上传操作 webview.evaluateJavascript("document.querySelector('input[type=file]').click()", null); } } }
如果提示@NonNull找不到,导入对应的包即可:import androidx.annotation.NonNull;
适配说明
- 你现有的
activity_main.xml和AndroidManifest.xml已经满足基础需求,无需修改 - 如果你需要适配Android 13及以上版本,需要将
READ_EXTERNAL_STORAGE权限替换为READ_MEDIA_IMAGES、READ_MEDIA_VIDEO,并在Manifest中同步添加对应声明
内容的提问来源于stack exchange,提问作者Na na
相关产品推荐
相关产品推荐

