当前位置:首页 > 行业动态 > 正文

安卓存储图片

安卓存储图片  第1张

安卓存储图片可通过FileOutputStream写入内部/外部存储,或用MediaStore API保存至公有目录,需处理运行时权限及Android 10+分区存储限制,Bitmap可压缩为PNG/JPEG格式

安卓存储图片的实现方式

内部存储(Internal Storage)

  • 特点:无需申请权限,数据与应用绑定,卸载应用时自动清除。
  • 适用场景:私密图片存储,仅当前应用可访问。
  • 实现步骤
    1. 获取内部存储目录:
      File dir = context.getFilesDir(); // 或 getCacheDir() 缓存目录
      File file = new File(dir, "image_" + System.currentTimeMillis() + ".png");
    2. 保存图片到文件:
      try (OutputStream os = new FileOutputStream(file)) {
          bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
      }
    3. 读取图片:
      Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());

外部存储(External Storage)

  • 特点:需申请权限,数据可被其他应用或用户访问。
  • 权限配置
    • Android 10以下:<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    • Android 10及以上:需使用Scoped Storage,通过MediaStore API。
  • 实现步骤(Android 10+):
    // 保存到公共图片目录
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.DISPLAY_NAME, "image_" + System.currentTimeMillis() + ".png");
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
    Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    try (OutputStream os = context.getContentResolver().openOutputStream(uri)) {
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
    }

SQLite数据库存储

  • 特点:适合少量小图片,存储为BLOB或Base64字符串。
  • 实现步骤
    1. 将Bitmap转换为字节数组:
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
      byte[] data = baos.toByteArray();
    2. 存入数据库:
      INSERT INTO Images (image_blob) VALUES (?)
    3. 读取并解码:
      Cursor cursor = db.rawQuery("SELECT image_blob FROM Images LIMIT 1", null);
      cursor.moveToFirst();
      byte[] data = cursor.getBlob(0);
      Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

ContentProvider存储(如MediaStore)

  • 特点:系统级存储,支持跨应用共享,兼容Android Q+限制。
  • 实现步骤
    // 写入MediaStore(Android Q+)
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.DISPLAY_NAME, "image_" + System.currentTimeMillis() + ".png");
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
    values.put(MediaStore.Images.Media.IS_PENDING, 1); // 标记为待处理
    Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    // 写入实际数据
    try (OutputStream os = context.getContentResolver().openOutputStream(uri)) {
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
    }
    // 更新状态
    ContentValues updateValues = new ContentValues();
    updateValues.put(MediaStore.Images.Media.IS_PENDING, 0);
    context.getContentResolver().update(uri, updateValues, null, null);

云存储(如Firebase Storage)

  • 特点:依赖网络,适合跨设备同步。
  • 实现步骤
    FirebaseStorage storage = FirebaseStorage.getInstance();
    StorageReference ref = storage.getReference().child("images/" + uuid + ".png");
    ref.putFile(file).addOnSuccessListener(taskSnapshot -> {
        ref.downloadUrl().addOnSuccessListener(uri -> {
            // 获取下载URL
        });
    });

存储方式对比表

存储方式 权限要求 数据持久性 是否可共享 适用场景
内部存储 应用卸载后清除 临时/私密图片
外部存储 运行时权限 长期存在 用户共享图片
SQLite 长期存在 小图片+结构化数据
MediaStore Android 10+特殊处理 长期存在 多媒体文件共享
云存储 无(依赖SDK) 长期存在 跨设备同步

相关问题与解答

问题1:如何选择图片存储方式?

  • 解答
    • 临时图片:使用内部存储或缓存目录(getCacheDir())。
    • 用户共享图片:使用外部存储或MediaStore(Android Q+)。
    • 小图标/缩略图:存入SQLite或SharedPreferences。
    • 跨应用/设备共享:通过ContentProvider或云存储。

问题2:Android 10+外部存储权限如何适配?

  • 解答
    • Scoped Storage:使用MediaStore API替代直接文件路径。
    • 临时权限:申请READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE时需动态请求,且仅能访问应用专属目录。
    • 替代方案:使用ACTION_OPEN_DOCUMENTStorage Access Framework选择
0