android - Android BitmapFactory 在一个应用程序中有效,但在另一个应用程序中无效
问题描述
我编写了一个包含以下代码的库。此代码的目的是从文件路径中获取位图对象并在需要时对其进行旋转:
private fun rotateBitmap(imageURI: String) : File {
val options = BitmapFactory.Options()
val bitmap = BitmapFactory.decodeFile(imageURI, options)
val rotation = getRotation() // some function, always returns null in this scenario
var newBitmap = if (rotation != 0f) {
//New rotation matrix
val matrix = Matrix()
matrix.preRotate(rotation)
//Bitmap.createBitmap(bitmap, 0, 0, 1000, 1000, matrix, true)
Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
} else {
//No need to rotate
BitmapFactory.decodeFile(imageURI, options)
}
// ..... do some more stuff
}
我在三个不同的应用程序中使用这个库。这些应用程序几乎相同,除了一些资源,如字符串、颜色等。它们都工作相同,打开图库让用户选择本地图片并将该图片的文件路径作为imageURI
参数传递给此方法。此功能只编写一次并由所有人以相同的方式使用,因此实现上的差异是不可能的,因为它们共享相同的代码。
在所有三个应用程序中,我选择了相同的文件,这使得imageURI
每个应用程序都通过相同的文件。rotation
始终为 0,这意味着库始终执行该部分else
。通过调试我知道这三个应用程序运行rotateBitmap
完全一样,除了返回值decodeFile
.
在应用程序中A
,B
它按预期工作。在 AppC
中,它总是返回null
,bitmap
和newBitmap
,而不抛出任何 Exception
.
所有三个应用程序都具有相同的权限。
像内存这样的资源的行为也几乎完全相同,因为正如我所说,这些应用程序几乎相同。
我检查了文档和一些 SO 问题/答案:
- BitmapFactory.decodeFile() 返回 null
- 位图从 BitmapFactory.decodeFile(filename) 返回 null
- Android:decodeFile 总是为内部存储中的文件返回 null
但他们都没有解决或解释看似不确定的行为。
关于如何解释和/或解决这个问题的任何想法都会有所帮助。
编辑:
正如CommonsWare所建议的,错误可能发生在imageURI
确定的地方。这部分在所有三个应用程序中的工作方式也完全相同,并且在所有三个应用程序中的结果都相同imageURI
。所以在这里我包括确定它的代码:
开始挑选图像的活动
(获得许可后)
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
intent.putExtra(
MediaStore.EXTRA_OUTPUT,
Uri.fromFile(File(getExternalStorageDirectory(), "chosenImage"))
)
val photoIntent = Intent.createChooser(intent, "Select Picture")
startActivityForResult(photoIntent, PickImage)
处理活动响应
uri = "content://com.android.providers.media.documents/document/image%3A24655"
final String docId = DocumentsContract.getDocumentId(uri);
final String [] split = docId . split (":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String [] selectionArgs = new String[]{
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
uri = "content://media/external/images/media"
selection = "_id=?"
selectionArgs = ["24655"]
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs)
{
Cursor cursor = null;
final String column = "_data";
final String [] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
结果imageURI
看起来像这样 =/storage/emulated/0/Download/tenor (1).gif
它是一个下载的图像。
编辑2:
我没有注意到C
具有不良行为的 App 是用 和 编译的compileSdkVersion 29
,targetSdkVersion 29
而其他的则是用28/28
.
所以我尝试用compileSdkVersion 29
and编译targetSdkVersion 28
。这使它起作用。但是,当我用 覆盖时29/29
,它也有效。
卸载并从头开始编译后compileSdkVersion 29
,targetSdkVersion 29
它再次不起作用。
所以。
- 28/28 - 作品
- 29/29 - 不起作用
- 29/28 - 作品
- 29/28 并用 29/29 覆盖 - 有效
- 29/28,卸载,重新安装 29/29 - 不起作用
仍然需要知道为什么以及如何发生这种行为,以便我将来可以更新。
解决方案
推荐阅读
- amazon-web-services - 如何用其他 ec2 实例图像替换 ec2 图像?
- node.js - 未处理的拒绝 MongoError: '$inc' 中的美元 ($) 前缀字段 '$inc' 对存储无效
- java - 当我使用千分尺的 PrometheusMeterRegistry 时,指标没有出现在普罗米修斯端点
- swift - 如何在运行时将 CIFilters 添加到视频中
- java - 如何在android中上传到服务器之前调整和压缩文件(pdf,xls,doc,pptx,.....等)base64
- php - 使用 XAMPP 和 Windows 一次又一次地收到错误“无法对套接字执行操作...”
- mysql - 从 Sequelize 中的两个不同的连接(包括)获取“总和”
- python-3.x - RabbitMQ Pika 连接重置 , (-1, ConnectionResetError(104, 'Connection reset by peer'))
- bots - 如何从 botpress 中的快速回复中获取有效负载
- hyperledger-fabric - Hyperledger Fabric 数据机密性