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

Android 14下使用ImageCapture拍摄照片如何保存至系统相册?

解决Android 14下ImageCapture照片无法显示在系统相册的问题

问题原因

你当前使用getExternalFilesDir(Environment.DIRECTORY_DCIM)保存照片,这个目录属于应用专属外部存储区域,系统媒体扫描器不会监控该目录,因此照片无法被系统相册识别。

解决方案:改用MediaStore写入公共DCIM目录

Android 10(API 29)及以上官方推荐使用MediaStore API向公共媒体目录写入文件,这样系统相册会自动识别新增的照片。以下是修改后的完整实现:

1. 配置权限

在AndroidManifest.xml中添加对应权限:

<!-- Android 13+ 读取媒体权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<!-- Android 12及以下 写入外部存储权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />

注:Android 14无需申请WRITE_EXTERNAL_STORAGE,通过MediaStore写入公共目录无需该权限。

2. 修改拍照保存逻辑

public void takePicture(ImageCapture imageCapture) {
    // 构建媒体文件的元数据
    ContentValues contentValues = new ContentValues();
    contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, System.currentTimeMillis() + ".jpg");
    contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
    // 保存到DCIM下的自定义子目录,也可直接写Environment.DIRECTORY_DCIM
    contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM + "/MyCamera");

    ContentResolver resolver = getContentResolver();
    // 向MediaStore插入条目,获取文件Uri
    Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);

    if (imageUri == null) {
        runOnUiThread(() -> Toast.makeText(MainActivity.this, "无法创建媒体条目", Toast.LENGTH_SHORT).show());
        startCamera(cameraFacing);
        return;
    }

    // 基于Uri构建ImageCapture的输出配置
    ImageCapture.OutputFileOptions outputFileOptions =
            new ImageCapture.OutputFileOptions.Builder(resolver, imageUri).build();

    imageCapture.takePicture(outputFileOptions, Executors.newSingleThreadExecutor(),
            new ImageCapture.OnImageSavedCallback() {
                @Override
                public void onImageSaved(ImageCapture.OutputFileResults outputFileResults) {
                    runOnUiThread(() -> {
                        Toast.makeText(MainActivity.this, "照片已保存至系统相册", Toast.LENGTH_SHORT).show();
                        // 手动触发媒体扫描,确保相册立即刷新(部分系统可能自动触发)
                        MediaScannerConnection.scanFile(MainActivity.this,
                                new String[]{imageUri.getPath()},
                                new String[]{"image/jpeg"},
                                (path, uri) -> {});
                    });
                    startCamera(cameraFacing);
                }

                @Override
                public void onError(ImageCaptureException exception) {
                    runOnUiThread(() ->
                            Toast.makeText(MainActivity.this, "保存失败: " + exception.getMessage(), Toast.LENGTH_SHORT).show());
                    // 保存失败时删除无效的MediaStore条目
                    resolver.delete(imageUri, null, null);
                    startCamera(cameraFacing);
                }
            });
}

核心说明

  • 公共目录写入:通过MediaStore.Images.Media.EXTERNAL_CONTENT_URI插入条目,直接将照片写入系统公共DCIM目录,系统相册会自动扫描该目录下的文件。
  • 媒体扫描优化:调用MediaScannerConnection.scanFile可以确保照片立即在相册中显示,避免部分系统延迟识别的问题。
  • 权限兼容:针对不同Android版本配置对应权限,既满足旧版本需求,又符合Android 14的权限规范。

内容的提问来源于stack exchange,提问作者Huraweurg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 11:10:34