Android WebView文件上传选项无法使用,请求技术修复
修复WebView文件上传按钮失效问题
WebView默认不处理文件上传的Intent请求,需要补充以下逻辑解决问题:
1. 核心修改点
- 自定义
WebChromeClient实现文件选择回调 - 处理文件选择后的结果返回
- 配置必要的权限
修改后的完整代码
public class MainActivity extends AppCompatActivity { private static final int FILE_CHOOSER_REQUEST_CODE = 100; private ValueCallback<Uri[]> mFilePathCallback; ActivityMainBinding binding; WebView mWebView; public String url = "https://google.com/"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); Log.d("MainActivity", "Main Activity Open"); mWebView = binding.myWebView; ProgressDialog progress = new ProgressDialog(this); progress.setTitle("Loading"); progress.setMessage("Wait while loading..."); progress.setCancelable(false); progress.show(); WebSettings webSettings = mWebView.getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setLoadWithOverviewMode(true); webSettings.setUseWideViewPort(true); webSettings.setBuiltInZoomControls(true); webSettings.setPluginState(WebSettings.PluginState.ON); // 启用文件访问权限 webSettings.setAllowFileAccess(true); webSettings.setAllowContentAccess(true); mWebView.setWebViewClient(new WebViewClient()); // 设置自定义WebChromeClient处理文件上传请求 mWebView.setWebChromeClient(new WebChromeClient() { @Override public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) { // 释放旧的回调避免内存泄漏 if (mFilePathCallback != null) { mFilePathCallback.onReceiveValue(null); } mFilePathCallback = filePathCallback; // 启动系统文件选择器 Intent intent = fileChooserParams.createIntent(); try { startActivityForResult(intent, FILE_CHOOSER_REQUEST_CODE); } catch (ActivityNotFoundException e) { mFilePathCallback = null; Toast.makeText(MainActivity.this, "无法打开文件选择器", Toast.LENGTH_SHORT).show(); return false; } return true; } }); if (!DetectConnection.checkInternetConnection(this)) { mWebView.loadUrl("file:///android_asset/error.html"); } else { mWebView.loadUrl(url); } progress.dismiss(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode != FILE_CHOOSER_REQUEST_CODE) { return; } Uri[] results = null; // 处理选择的文件结果 if (resultCode == Activity.RESULT_OK && data != null) { ClipData clipData = data.getClipData(); String dataString = data.getDataString(); if (clipData != null) { results = new Uri[clipData.getItemCount()]; for (int i = 0; i < clipData.getItemCount(); i++) { results[i] = clipData.getItemAt(i).getUri(); } } else if (dataString != null) { results = new Uri[]{Uri.parse(dataString)}; } } // 将结果返回给WebView if (mFilePathCallback != null) { mFilePathCallback.onReceiveValue(results); mFilePathCallback = null; } } // 处理权限申请结果 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) { Toast.makeText(this, "需要存储权限才能上传文件", Toast.LENGTH_SHORT).show(); } } }
权限配置(AndroidManifest.xml)
在清单文件中添加对应权限:
<!-- Android 12及以下版本 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Android 13及以上版本 --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
额外说明
- 若使用AndroidX,建议用
registerForActivityResult替代已废弃的onActivityResult - 测试前确认网页的上传表单本身功能正常,排除网页端问题
内容的提问来源于stack exchange,提问作者Andy Jadeja
相关产品推荐
相关产品推荐

