gpt4 book ai didi

android - 将图片保存到共享图片文件夹 android target api 29

转载 作者:行者123 更新时间:2023-12-03 17:27:13 27 4
gpt4 key购买 nike

我的目标是从相机应用程序请求图片,将其保存在我的应用程序数据中,并将相同的图片写入图库,因此如果用户删除应用程序,它仍然有拍摄的照片(与信使不同,我们的实用工具图片被认为对用户非常有值(value),即使没有应用程序)。

我面临的问题与 29 API 级别的女巫密切相关是构建目标(提供降级是 Not Acceptable )。

所以基本上我得到的是:

第一个问题 : 即使是 Manifest.permission.WRITE_EXTERNAL_STORAGE授予我无法访问使用 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) 构建的文件我得到 IOException(权限被拒绝)

第二题 : contentResolver.insert(contentUri, contentValues)在 pre Q 设备(诺基亚 8 Android Pie)上抛出这个:

java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from .... requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()

如果我在 Android 10 设备(在我的情况下为模拟器)上运行,则使用 contentResolver.insert(..) 的选项工作正常。

主要问题 以 29Api 级别为目标时,如何将图片正确写入 android 管理的画廊文件夹,以便它可以在 android 10 之前的设备上运行?

额外引用

我将图片从我的应用缓存存储写入 android 10 库的代码是:
    fun writePictureToGalleryQ(context: Context, pictureUri: Uri, pictureName: String) {

val contentResolver = context.contentResolver

val relativeLocation = "${Environment.DIRECTORY_PICTURES}${File.separator}WaiJuDuDisAndroid"

val contentValues = ContentValues().apply {
put(MediaStore.Images.ImageColumns.DISPLAY_NAME, pictureName)
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
put(MediaStore.Images.ImageColumns.RELATIVE_PATH, relativeLocation)
}

val contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
var uri: Uri? = null

uri = contentResolver.insert(contentUri, contentValues)
uri?.let { galleryPartUri ->

val outStream: OutputStream = contentResolver.openOutputStream(galleryPartUri)!!
val inStream: InputStream = contentResolver.openInputStream(pictureUri)!!

outStream.use {out ->
inStream.use { inpt ->
inpt.copyTo(out)
}
}
}
}

附:内容提供者在 list 以及所需的权限和文件路径 xml 中设置。

应该为每个 Q android 版本执行的代码,但它看起来不像这样(假设我已经得到 Manifest.permission.WRITE_EXTERNAL_STORAGE )
    fun writePictureToGalleryLegacy(context: Context, pictureUri: Uri, pictureName: String) {


val directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)

val correctDir = File("${directory.absolutePath}${File.separator}WaiJuDuDisAndroid")
correctDir.mkdirs()

val file = File("${correctDir.absolutePath}${File.separator}${pictureUri.lastPathSegment}")

val contentResolver = context.contentResolver

val outStream: OutputStream = file.outputStream()
val inStream: InputStream = contentResolver.openInputStream(pictureUri)!!

outStream.use {out ->
inStream.use { inpt ->
inpt.copyTo(out)
}
}


val mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(file.extension)

MediaScannerConnection.scanFile(
context,
arrayOf(file.absolutePath),
arrayOf(mimeType?:"image/*"),
null
)

}


问题更新和编辑

我将我的代码块调整为更正确,因为它们确实有效。

重建项目最终解决了我的问题。不知道我更讨厌什么——谷歌还是我自己。

当然,重建项目只是解决方案的一部分。

我遇到了两个问题:
  • 这里有人删除了他的答案,说我可能缺少 <application... android:requestLegacyExternalStorage="true" ....>
  • 我的依赖项中的某些库有 android:maxSdkVersion在它的 list 中,基本上会导致忽略我对 Android 10 和 Android 9 设备以及可能从 Android 4.4 开始的所有设备的许可。

  • 因此,我相应地更改了我的应用 list :
    <manifest>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace"/>

    <application android:requestLegacyExternalStorage="true" ...>
    ...
    </application>

    </manifest>

    最佳答案

    有同样的问题,将扩展 Cordova 应用程序的解决方案,最终对我有用的是将此行添加到 config.xml :

    <platform name="android">
    <custom-preference name="android-manifest/application/@android:requestLegacyExternalStorage" value="true" />

    关于android - 将图片保存到共享图片文件夹 android target api 29,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59543110/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com