android - 无法使用 BitmapFactory.decodeFile 读取图像
问题描述
位图大小仅为 49 KB。
我在我的 AndroidManifest 中有权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
但是下面的代码返回null,它不能从文件中读取图像。
Im = BitmapFactory.decodeFile(file.absolutePath) // <== file: "/storage/emulated/0/Android/data/com.example.App1/files/MyImages/MyImg.png"
BitmapFactory.decodeFile返回 null。
我使用 Filestream 搜索并尝试了以下建议:
try {
val dest = File(fullPath, fileName) // dest: "/storage/emulated/0/Android/data/com.example.App1/files/MyImages/MyImage.png"
var fis: FileInputStream
fis = FileInputStream(dest) // <= Jumps to catch section from this line
Img = BitmapFactory.decodeStream(fis)
}
catch (e: Exception) {
Log.e("File could not be found", e.message)
}
return Img
但是,当我调试它时,光标会从 fis = FileInputStream(dest) 行跳转到 catch 部分。它给出了这个错误:
e=java.io.FileNotFoundException (No such file or directory)
当我将这个try-catch块放入“if”语句时,就像这样;
val file = File(fullPath, fileName)
if (file.exists()){
// the above try-catch block is here
}
那么条件“ file.exists() ”不正确(但我可以在设备中看到,文件存在。它与“ dest ”参数位于同一路径中,其值如您所见)
我保存了 PNG 文件,其中包含Bao Lei 给出的如何将位图保存到 android 库中的代码。这些代码如下:
/// @param folderName can be your app's name
private fun saveImage(bitmap: Bitmap, context: Context, folderName: String) {
if (android.os.Build.VERSION.SDK_INT >= 29) {
val values = contentValues()
values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/" + folderName)
values.put(MediaStore.Images.Media.IS_PENDING, true)
// RELATIVE_PATH and IS_PENDING are introduced in API 29.
val uri: Uri? = context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
if (uri != null) {
saveImageToStream(bitmap, context.contentResolver.openOutputStream(uri))
values.put(MediaStore.Images.Media.IS_PENDING, false)
context.contentResolver.update(uri, values, null, null)
}
} else {
val directory = File(Environment.getExternalStorageDirectory().toString() + separator + folderName)
// getExternalStorageDirectory is deprecated in API 29
if (!directory.exists()) {
directory.mkdirs()
}
val fileName = System.currentTimeMillis().toString() + ".png"
val file = File(directory, fileName)
saveImageToStream(bitmap, FileOutputStream(file))
if (file.absolutePath != null) {
val values = contentValues()
values.put(MediaStore.Images.Media.RELATIVE_PATH, folderName)
// .DATA is deprecated in API 29
context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
}
}
}
private fun contentValues() : ContentValues {
val values = ContentValues()
values.put(MediaStore.Images.Media.MIME_TYPE, "image/png")
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
return values
}
private fun saveImageToStream(bitmap: Bitmap, outputStream: OutputStream?) {
if (outputStream != null) {
try {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
outputStream.close()
} catch (e: Exception) {
e.printStackTrace()
}
}
}
if 语句;如果(android.os.Build.VERSION.SDK_INT >= 29)不正确。因此,只有剩余的else部分正在运行。在这个else部分,我删除了这段代码;
if (file.absolutePath != null) {
val values = contentValues()
values.put(MediaStore.Images.Media.DATA, file.absolutePath)
// .DATA is deprecated in API 29
context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
}
因为,它会导致此错误:
Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=14668, uid=10271 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()
因此,上面代码中的函数saveImageToStream保存了图像。
现在,关于读取 PNG 的问题是
e=java.io.FileNotFoundException (No such file or directory)
尽管PNG确实存在。如何解决这个问题呢 ?
代码fis = FileInputStream(dest)在 DidtodayActivity.kt 文件中。并且,此活动文件在清单文件中定义为:
<activity android:name=".DidtodayActivity">
<intent-filter>
<action android:name="com.mystudio.otherlab.MainActivity" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".secondActivity" />
<activity android:name=".loginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Manifest 文件有问题吗?
尽管路径正确且 PNG 文件确实存在,但为什么会出现错误(找不到文件)?我希望有人能帮帮忙
解决方案
这给了你什么
try {
// Img = BitmapFactory.decodeFile(file.absolutePath) //<= returns null
val dest = File(fullPath, fileName) // dest: "/storage/emulated/0/Android/data/com.example.App1/files/MyImages/MyImage.png"
System.out.println("DEST IS: " + dest); // <= Check this in Logcat
var fis: FileInputStream
fis = FileInputStream(dest) // <= Jumps to catch section from this line
Img = BitmapFactory.decodeStream(fis)
}
catch (e: Exception) {
Log.e("File could be find", e.message)
}