首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将图像保存在android q上的子目录中,同时保持向后兼容

问如何将图像保存在android q上的子目录中,同时保持向后兼容
EN

Stack Overflow用户
提问于 2019-07-14 20:36:21
回答 4查看 10.4K关注 0票数 23

我正在创建一个简单的图像编辑器应用程序,因此需要加载和保存图像文件。我希望保存的文件出现在一个单独的相册画廊。从Android 28到29,应用程序能够访问存储的程度发生了巨大的变化。我可以在Android (API 29)中做我想做的事情,但是这种方式并不是向后兼容的。

当我想在较低的API版本中获得相同的结果时,到目前为止,我只找到了方法,这需要使用废弃的代码(从API 29开始)。

其中包括:

  • MediaStore.Images.Media.DATA列的使用
  • 通过Environment.getExternalStoragePublicDirectory(...)获取到外部存储的文件路径
  • 通过MediaStore.Images.Media.insertImage(...)直接插入图像

我的问题是:是否有可能以这种方式实现它,因此它是向后兼容的,但不需要被弃用的代码?如果没有,在这种情况下使用不推荐的代码可以吗?或者这些方法会很快从sdk中删除吗?在任何情况下,使用不推荐的方法感觉都很糟糕,所以我宁愿不使用:)

这就是我发现的使用API 29的方法:

代码语言:javascript
复制
ContentValues values = new ContentValues();
String filename = System.currentTimeMillis() + ".jpg";

values.put(MediaStore.Images.Media.TITLE, filename);
values.put(MediaStore.Images.Media.DISPLAY_NAME, filename);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.RELATIVE_PATH, "PATH/TO/ALBUM");

getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values);

然后使用insert方法返回的URI保存位图。问题是RELATIVE_PATH字段是在API 29中引入的,所以当我在较低版本上运行代码时,图像会被放入"Pictures“文件夹,而不是”PATH/TO/相册“文件夹。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-07-22 11:36:13

在这种情况下使用不推荐的代码可以吗?或者这些方法会很快从sdk中删除吗?

DATA选项不会在Android上工作,因为这些数据不包含在query()结果中,即使您请求它,也不能使用它返回的路径,即使它们被返回。

默认情况下,Environment.getExternalStoragePublicDirectory(...)选项不会在Android上工作,尽管您可以添加一个清单条目来重新启用它。但是,这个清单条目可能会在Android中被删除,所以除非你时间短,否则我不会走这条路。

AFAIK,MediaStore.Images.Media.insertImage(...)仍然工作,尽管它被废弃了。

是否有可能以这种方式实现它,因此它是向后兼容的,但不需要不推荐的代码?

我的猜测是,您需要使用两种不同的存储策略,一种用于API级别的29+,另一种用于旧设备。我在这个示例应用程序中采用了这种方法,尽管在那里我正在处理视频内容,而不是图像,所以insertImage()不是一种选择。

票数 7
EN

Stack Overflow用户

发布于 2020-06-26 19:05:16

这是对我有用的代码。此代码将图像保存到电话上的子目录文件夹中。它检查android版本的手机,如果它高于android,它运行所需的代码,如果它在下面运行代码,它将运行code语句中的代码。

来源:https://androidnoon.com/save-file-in-android-10-and-below-using-scoped-storage-in-android-studio/

代码语言:javascript
复制
 private void saveImageToStorage(Bitmap bitmap) throws IOException {
    OutputStream imageOutStream;
   
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.DISPLAY_NAME, 
        "image_screenshot.jpg");
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        values.put(MediaStore.Images.Media.RELATIVE_PATH, 
         Environment.DIRECTORY_PICTURES + File.pathSeparator + "AppName");

        Uri uri = 
     getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
    values);

        imageOutStream = getContentResolver().openOutputStream(uri);

    } else {

        String imagesDir = 
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES). toString() + "/AppName";
        File image = new File(imagesDir, "image_screenshot.jpg");
        imageOutStream = new FileOutputStream(image);
    }

   
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, imageOutStream);
        imageOutStream.close();
    

}
票数 3
EN

Stack Overflow用户

发布于 2020-09-22 19:31:02

对于旧API (<29),我将图像放入外部媒体目录并通过MediaScannerConnection进行扫描。

让我们看看我的密码。

此函数创建一个图像文件。注意一个appName变量--它是一个会显示图像的相册的名称。

代码语言:javascript
复制
override fun createImageFile(appName: String): File {
    val dir = File(appContext.externalMediaDirs[0], appName)
    if(!dir.exists()) {
        ir.mkdir()
    }

    return File(dir, createFileName())
}

然后,我将一个图像放到文件中,最后,我运行了这样一个媒体扫描仪:

代码语言:javascript
复制
private suspend fun scanNewFile(shot: File): Uri? {
    return suspendCancellableCoroutine { continuation ->
        MediaScannerConnection.scanFile(
            appContext, 
            arrayOf<String>(shot.absolutePath), 
            arrayOf(imageMimeType)) { _, uri -> continuation.resume(uri)
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57030990

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档