Android SDK30 WebView相机上传时intent.getDataString()返回null问题咨询
问题根因
Android 11(API 30)对ACTION_IMAGE_CAPTURE拍照行为做了调整:如果你给拍照Intent指定了MediaStore.EXTRA_OUTPUT参数,拍照成功后返回的Intent会为空,不会携带任何data数据,因此intent.getDataString()自然返回null,这是系统的预期行为,不是代码bug。
修复步骤
1. 调整拍照Uri存储逻辑
你之前存储的是file://协议的本地路径,高版本WebView禁止直接访问file协议资源,需要改为存储FileProvider生成的content协议Uri,同时给拍照Intent授予临时写入权限:
if (photoFile != null) { Uri imgUrl; if (getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.M) { String authority = getPackageName(); imgUrl = FileProvider.getUriForFile(MainActivity.this, authority, photoFile); } else { imgUrl = Uri.fromFile(photoFile); } // 存储content协议的Uri字符串,而非file路径 cam_file_data = imgUrl.toString(); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imgUrl); // 给相机应用授予临时写入权限,确保照片能正常保存到指定路径 takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); }
2. 修复onActivityResult空指针逻辑
针对拍照场景返回空Intent的情况,优先使用提前存储的拍照Uri,避免空指针:
} else { if (stringData != null) { // 从相册选图的场景,走原有逻辑 results = new Uri[]{Uri.parse(stringData)}; } else if (cam_file_data != null) { // 拍照场景,直接用提前存储的Uri results = new Uri[]{Uri.parse(cam_file_data)}; } }
同时每次用完Uri后要重置全局变量,避免后续调用出现脏数据:
file_path.onReceiveValue(results); file_path = null; // 新增:重置拍照Uri存储变量 cam_file_data = null;
3. 适配Android 11包可见性规则(必加)
API 30引入了包可见性限制,未声明查询权限的情况下,takePictureIntent.resolveActivity()可能返回null,导致相机选项消失。需要在AndroidManifest.xml的manifest根节点下添加如下配置:
<queries> <intent> <action android:name="android.media.action.IMAGE_CAPTURE" /> </intent> </queries>
4. 权限申请优化(可选)
Android 10及以上版本不需要WRITE_EXTERNAL_STORAGE权限即可访问app专属外部存储,你可以调整权限申请逻辑,仅在API < 29的设备上申请该权限,减少不必要的权限弹窗。
5. FileProvider路径优化(可选)
你当前创建的照片存储在getExternalFilesDir(Environment.DIRECTORY_PICTURES)目录下,属于app专属外部存储,将provider_paths.xml的配置调整为更精准的路径,避免权限溢出:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="app_images" path="Pictures" /> </paths>
内容的提问来源于stack exchange,提问作者dc09

