迁移到 Android Q 的作用域存储

4
当用户在我的应用程序中拍照时,图像将保存在内部存储器中。我还允许将它们移动到外部存储器中,这样他们就可以通过将设备插入计算机并从那里获取它们。我会通过以下方式实现:
当用户在我的应用程序中拍照时,图像将保存在内部存储器中。我还允许将它们移动到外部存储器中,这样他们就可以通过将设备插入计算机并从那里获取它们。
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()
}

我希望图片保存在文件夹中

现在尝试切换到以支持,但不确定如何将文件保存到同一文件夹中。

我已经尝试过:

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时缺少了一些基础知识,不确定具体是什么。


你实际上并没有保存那张图片。我还没有在Q上测试过范围存储的东西,但我相当确定你只需要使用返回的uri调用 ContentResolver#openOutputStream() ,然后将你的 baseFile 写入其中。 - Mike M.
啊,好的,让我试试。 - tyczj
1
@MikeM。是的,就是这样,谢谢! - tyczj
1个回答

5
正如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()
        }
    }

1
为什么要使用 MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY) 而不是 MediaStore.Images.Media.EXTERNAL_CONTENT_URI? - shaktisinghmoyal
@tyczj 怎么在Java中处理PDF文件? - jazzbpn
https://stackoverflow.com/questions/63480192/how-to-save-and-store-pdf-file-in-a-folder-using-scoped-storage-in-android-10-an - jazzbpn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接