API 33+ 相机拍照后触发java.lang.NullPointerException: uri异常求助
解决拍照后因Uri空指针崩溃的问题
问题分析
应用拍照功能完成后崩溃,报错java.lang.NullPointerException: uri,堆栈显示错误发生在HomeActivity.onActivityResult调用ContentResolver.openInputStream时。图库功能正常,问题出在拍照流程的Uri处理上:
- 当通过
intent.putExtra("output", uri)指定相机输出路径后,相机不会将Uri放入返回的Intent(data)中,若代码尝试从data里提取Uri,必然得到null。 dispatchTakePictureIntent方法中,uri变量未初始化,若intent.resolveActivity返回null,会直接返回未设置output的Intent,存在潜在风险。
解决方案
1. 复用预存的照片路径
在ImageCaptureManager中添加获取照片路径的方法,直接使用拍照前生成的路径,而非从返回的Intent中提取Uri:
// ImageCaptureManager类中添加 public String getCurrentPhotoPath() { return mCurrentPhotoPath; }
2. 修复Uri初始化问题
确保dispatchTakePictureIntent中Uri始终被初始化,同时使用Android官方常量替代硬编码字符串:
public Intent dispatchTakePictureIntent() throws IOException { Uri uri = null; // 初始化Uri变量 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (intent.resolveActivity(mContext.getPackageManager()) != null) { File imageFile = createImageFile(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { uri = FileProvider.getUriForFile(mContext.getApplicationContext(), mContext.getApplicationInfo().packageName + ".provider", imageFile); } else { uri = Uri.fromFile(imageFile); } if (uri != null) { intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); } } return intent; }
3. 修正onActivityResult逻辑
直接使用预存的照片路径构建Uri,避免从返回的Intent中获取:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1 && resultCode == RESULT_OK) { String photoPath = imageCaptureManager.getCurrentPhotoPath(); if (photoPath != null) { File photoFile = new File(photoPath); Uri photoUri; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { photoUri = FileProvider.getUriForFile(this, getPackageName() + ".provider", photoFile); } else { photoUri = Uri.fromFile(photoFile); } // 处理图片输入流 try (InputStream inputStream = getContentResolver().openInputStream(photoUri)) { // 你的图片处理逻辑 } catch (IOException e) { e.printStackTrace(); } } } }
4. 验证FileProvider配置
确保AndroidManifest.xml中正确配置FileProvider:
<application> <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application>
在res/xml目录下创建file_paths.xml,指定文件访问路径:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="pictures" path="Pictures" /> </paths>
内容的提问来源于stack exchange,提问作者JustMeShortie
相关产品推荐
相关产品推荐

