You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:13:41