安卓相机拍照保存后Activity不返回且崩溃(红米等机型异常)
解决拍照后返回Activity崩溃(红米等机型)的问题
看起来你遇到了一个典型的Android厂商适配问题——三星上拍照正常,红米等机型却崩溃,核心原因是不同厂商的相机Intent返回逻辑不一致导致的空指针异常。让我帮你一步步拆解并解决这个问题:
错误根源分析
从错误栈和你的代码来看,崩溃发生在Home.java的第101行,也就是uri.toString()这一步——data.getData()返回了null。
三星的相机应用在拍照后会通过data返回图片的Uri,但红米等多数机型的相机实现逻辑不同:当你没有指定拍照图片的保存路径时,系统不会通过data.getData()返回Uri,直接调用toString()就触发了NullPointerException。
你的当前代码直接假设data.getData()一定不为null,这就是问题所在:
Uri uri = data.getData(); Log.e("Image : ", uri.toString()); // 这里uri为null时必然崩溃
解决方案:指定拍照保存路径
正确的做法是主动定义拍照图片的保存路径,不依赖系统相机的返回数据,这样不管什么机型都能稳定获取图片。
步骤1:启动相机前定义保存Uri
在唤起相机Intent之前,先创建一个用于存储拍照图片的文件,并通过FileProvider生成Uri(适配Android 7.0及以上的文件权限要求):
private Uri photoUri; // 全局变量保存拍照Uri // 唤起相机的方法 private void launchCamera() { Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 检查设备是否有相机应用 if (cameraIntent.resolveActivity(getPackageManager()) != null) { File photoFile = null; try { photoFile = createTempImageFile(); } catch (IOException e) { e.printStackTrace(); Toast.makeText(this, "创建图片文件失败", Toast.LENGTH_SHORT).show(); return; } if (photoFile != null) { // 用FileProvider生成Uri,适配Android N+ photoUri = FileProvider.getUriForFile(this, "com.logiclump.technologies.gigmedico.fileprovider", // 替换成你的App的FileProvider授权名 photoFile); // 告诉相机把图片保存到这个Uri cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); startActivityForResult(cameraIntent, CAMERA_REQUEST_CODE); } } } // 创建临时图片文件的工具方法 private File createTempImageFile() throws IOException { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); String imageFileName = "GIGMEDICO_" + timeStamp + "_"; // 存在应用私有目录,无需动态申请存储权限(Android 10+) File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); return File.createTempImageFile(imageFileName, ".jpg", storageDir); }
步骤2:修改onActivityResult逻辑
不再依赖data.getData(),直接使用我们预先保存的photoUri:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // 必须调用super方法 if (requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK) { if (photoUri != null) { Log.e("Image : ", photoUri.toString()); Intent intent = new Intent(this, PictureActivity.class); intent.putExtra("imgUrl", photoUri.toString()); startActivity(intent); } else { Toast.makeText(this, "拍照失败,请重试", Toast.LENGTH_SHORT).show(); } } }
步骤3:配置FileProvider(Android 7.0+必填)
- 在
AndroidManifest.xml中添加FileProvider配置:
<application> ... <provider android:name="androidx.core.content.FileProvider" android:authorities="com.logiclump.technologies.gigmedico.fileprovider" 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"> <!-- 授权访问应用外部存储的Pictures目录 --> <external-files-path name="camera_photos" path="Pictures" /> </paths>
额外优化:PictureActivity添加空判断
为了避免后续环节的异常,在PictureActivity中也增加空指针判断:
Bundle bundle = getIntent().getExtras(); if (bundle != null) { String imgUrlStr = bundle.getString("imgUrl"); Log.e("ashish", imgUrlStr + ""); if (imgUrlStr != null) { Uri path = Uri.parse(imgUrlStr); ImageView selfiiii = findViewById(R.id.mySelfie); selfiiii.setImageURI(path); } }
这样修改后,不管是三星还是红米等其他机型,拍照后都能稳定获取图片Uri,彻底解决崩溃问题。
内容的提问来源于stack exchange,提问作者mohd irfan
相关产品推荐
相关产品推荐

