Android Nougat拍照后裁剪显示至ImageView报错问题求助
解决Android Nougat拍照后图片无法显示到ImageView的问题
嘿,我看了你在Nougat上遇到的拍照显示问题,结合你贴的代码,发现几个关键的小问题,这应该就是导致Marshmallow正常但Nougat出错的原因,咱们一步步来修复:
1. Intent权限标记用错了!
你代码里用intent.setFlags()来添加读写权限,但setFlags()是直接覆盖Intent所有原有标记,不是追加。相机的IMAGE_CAPTURE Intent本身有默认的必要标记,被你覆盖后就出问题了。赶紧改成addFlags():
// 把原来的setFlags换成addFlags intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
2. 裁剪功能的权限和Intent配置有问题
你贴的裁剪代码没写完,但能看到你刚给裁剪应用授予权限就马上撤销了——这等于白给,裁剪应用根本拿不到Uri的访问权限,不出错才怪。而且裁剪Intent也得适配FileProvider,给你补个完整的裁剪方法:
private void performCrop() { try { Intent cropIntent = new Intent("com.android.camera.action.CROP"); cropIntent.setDataAndType(uri, "image/*"); // 基础裁剪配置,你可以按需调整比例和尺寸 cropIntent.putExtra("crop", "true"); cropIntent.putExtra("aspectX", 1); cropIntent.putExtra("aspectY", 1); cropIntent.putExtra("outputX", 256); cropIntent.putExtra("outputY", 256); cropIntent.putExtra("return-data", false); // 不要返回小图,直接写到文件 // 准备裁剪后的输出文件,同样用FileProvider适配Nougat File cropFile = new File(getExternalCacheDir(), "cropped_" + System.currentTimeMillis() + ".jpg"); Uri cropUri; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { cropUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", cropFile); // 给裁剪应用临时权限,用addFlags追加 cropIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); cropIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); } else { cropUri = Uri.fromFile(cropFile); } cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, cropUri); startActivityForResult(cropIntent, 200); // 用新的请求码区分裁剪结果 } catch (ActivityNotFoundException e) { Toast.makeText(this, "找不到合适的裁剪应用", Toast.LENGTH_SHORT).show(); } }
3. onActivityResult里要正确处理结果
别忘了在onActivityResult里区分拍照和裁剪的结果,然后用ContentResolver加载图片(Nougat不能直接用File路径了):
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { if (requestCode == 100) { // 拍照完成,触发裁剪 performCrop(); } else if (requestCode == 200) { // 裁剪完成,加载到ImageView try { // 注意这里要用裁剪后的cropUri,或者你也可以直接用拍照的uri(如果不裁剪的话) Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(cropUri)); yourImageView.setImageBitmap(bitmap); } catch (FileNotFoundException e) { e.printStackTrace(); Toast.makeText(this, "图片加载失败", Toast.LENGTH_SHORT).show(); } } } }
最后再检查两个配置点
- 确认
AndroidManifest.xml里的FileProvider配置正确:
<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>
res/xml/file_paths.xml要包含你用的外部缓存目录:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-cache-path name="external_cache" path="." /> </paths>
这些改动应该能解决你在Nougat上的问题,核心就是别乱覆盖Intent标记,正确给第三方应用(相机、裁剪)授予Uri临时权限,还有适配FileProvider的Uri处理。
内容的提问来源于stack exchange,提问作者Sunil P
相关产品推荐
相关产品推荐

