Android相机高质量拍照异常:部分机型无返回或崩溃求助
解决Android高质量拍照时的URI异常与崩溃问题
我之前在做Android相机适配的时候,踩过不少厂商高质量拍照的坑,你的情况简直一模一样——低/中等质量正常,一切到高质量就各种奇葩问题,本质上是不同厂商对大尺寸照片的MediaStore写入逻辑、权限处理差异导致的。给你几个实用的解决方案:
1. 自己指定拍照文件路径,彻底摆脱相机返回URI的坑
别依赖相机APP自动生成MediaStore条目了,自己创建文件并指定路径,不管照片质量多高,都能准确拿到文件:
第一步:创建拍照临时文件
private File mPhotoFile; // 全局变量,保存拍照文件路径 private File createImageFile() throws IOException { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); String imageFileName = "HQ_PHOTO_" + timeStamp + "_"; // 存在应用私有目录,不需要WRITE_EXTERNAL_STORAGE权限(Android 10+) File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); return File.createTempFile(imageFileName, ".jpg", storageDir); }
第二步:用FileProvider启动相机
Android 7.0+不能直接用File URI,必须用FileProvider:
private static final int REQUEST_CAMERA = 1001; private void startHighQualityCamera() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) == null) { Toast.makeText(this, "没有可用的相机应用", Toast.LENGTH_SHORT).show(); return; } try { mPhotoFile = createImageFile(); } catch (IOException e) { Toast.makeText(this, "创建拍照文件失败", Toast.LENGTH_SHORT).show(); e.printStackTrace(); return; } // 通过FileProvider生成安全的URI Uri photoUri = FileProvider.getUriForFile( this, "com.your.app.package.fileprovider", // 替换成你的应用包名+fileprovider mPhotoFile ); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); // 授予相机APP写入权限 takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); startActivityForResult(takePictureIntent, REQUEST_CAMERA); }
第三步:配置FileProvider
在AndroidManifest.xml里添加Provider配置:
<application> ... <provider android:name="androidx.core.content.FileProvider" android:authorities="com.your.app.package.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>
2. 处理返回结果时严格判空+异常捕获
不管用哪种方式,都要避免空指针和未处理的异常:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CAMERA && resultCode == RESULT_OK) { if (mPhotoFile != null && mPhotoFile.exists()) { // 直接读取文件,比如转成Bitmap try { Bitmap bitmap = BitmapFactory.decodeFile(mPhotoFile.getAbsolutePath()); // 处理你的高质量照片 } catch (Exception e) { Toast.makeText(this, "读取照片失败", Toast.LENGTH_SHORT).show(); e.printStackTrace(); } } else { // 处理文件不存在的情况,比如提示用户重拍 Toast.makeText(this, "拍照文件丢失", Toast.LENGTH_SHORT).show(); } } }
3. 针对特殊厂商的补充适配
- 三星机型:部分三星手机在高质量模式下会忽略
EXTRA_OUTPUT,直接把照片存到DCIM目录。可以在文件不存在时,去DCIM目录扫描最新创建的文件作为备选。 - HTC机型:你的NullPointerException就是因为相机返回的URI为null,现在用自己指定文件的方式就不会有这个问题了;如果一定要用系统返回的URI,记得先判空:
if (data != null && data.getData() != null)。 - 崩溃机型:检查是否动态申请了
CAMERA权限(Android 6.0+必须动态申请),同时确保Android 10+没有强制使用废弃的存储方式。
总结
自己指定拍照文件路径是最可靠的方案,彻底绕开了不同厂商对MediaStore的差异化处理,同时做好权限适配和异常捕获,就能解决高质量拍照的各种问题。
内容的提问来源于stack exchange,提问作者user9563163
相关产品推荐
相关产品推荐

