android - 迁移到适用于 Android Q 的范围存储

标签 android

当用户在我的应用中拍照时,图像会本地保存在内部存储中。我还允许将其移动到外部存储设备,然后他们可以通过将设备插入计算机并在需要时将它们从那里取出来抓取。

我会这样做

val tempDir = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "My_App_Folder")

val baseFile = File(filePath)
if(baseFile.exists()){
    val targetFile = File(directory.path+File.separator+targetFileName)
    baseFile.copyTo(targetFile)
    baseFile.delete()
}

图像最终会出现在 Pictures/My_App_Folder就像我想要的

现在尝试移至 MediaStore支持scoped storage我不确定如何将文件保存到同一个文件夹。

我试着做
val values:ContentValues = ContentValues()
values.put(MediaStore.Images.Media.MIME_TYPE,"image/jpg")
values.put(MediaStore.Images.Media.DATE_ADDED,System.currentTimeMillis() / 1000)
values.put(MediaStore.Images.Media.TITLE, targetFileName)
values.put(MediaStore.Images.Media.DISPLAY_NAME, targetFileName)
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
   values.put(MediaStore.Images.Media.DATE_TAKEN,System.currentTimeMillis())
   values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES+"/My_App_Folder")
   uri = contentResolver.insert(MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL),values)
}else{
   uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values)
}

但是现在该文件夹中没有任何内容,我觉得我缺少 MediaStore 的一些基本内容,我不确定它是什么

最佳答案

正如 Mike 指出的那样,在插入内容解析器后,我必须使用 uri 的输出流保存图像,因此向后兼容的示例如下所示。

private fun saveFileToExternalStorage(directory:File?,filePath:String,targetFileName:String){
        var uri:Uri? = null
        val values:ContentValues = ContentValues()
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
            values.put(MediaStore.Images.Media.MIME_TYPE,"image/jpg")
            values.put(MediaStore.Images.Media.DATE_ADDED,System.currentTimeMillis() / 1000)
            values.put(MediaStore.Images.Media.TITLE, targetFileName)
            values.put(MediaStore.Images.Media.DISPLAY_NAME, targetFileName)
            values.put(MediaStore.Images.Media.DATE_TAKEN,System.currentTimeMillis())
            values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES+"/My_App_Folder")
            values.put(MediaStore.Images.Media.IS_PENDING, 1)
            uri= contentResolver.insert(MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY),values)
        }

        val baseFile = File(filePath)
        if(baseFile.exists()){

            if(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q){
                directory?.let {
                    val targetFile = File(it.path+File.separator+targetFileName)
                    baseFile.copyTo(targetFile)
                }
            }else{
                uri?.let {
                    val outputStream: OutputStream? = contentResolver.openOutputStream(uri)
                    outputStream?.let{
                        val inputStream: InputStream = File(filePath).inputStream()
                        inputStream.copyTo(outputStream,1024)
                    }
                    values.clear()
                    values.put(MediaStore.Images.Media.IS_PENDING, 0)
                    contentResolver.update(uri,values,null,null)
                }
            }

            baseFile.delete()
        }
    }

关于android - 迁移到适用于 Android Q 的范围存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57362150/

相关文章:

android - 无法解析导入 android.support.v7.widget.RecyclerView;

android - Android应用程序如何拥有多个进程?

android - Bufferedreader.readline() 导致无限循环

javascript - 如何在Google Map iOS SDK上隐藏商业位置

android - 将 View 保存到图像 - 位置或不工作

android - 在 GridView 中将布局显示为项目

android - cocos2d-x v 2.0 和 Linux

android - 在 Android 中如何更改正在列表中搜索的特定字母/字符的颜色

java - 为什么我无法执行获取 java.lang.IllegalStateException 的 Activity 的方法?

android - 无法在设备上运行应用