在我的应用程序中从图库中选择图像时,它不会崩溃,而是无法解码路径流。直接从相机拍摄照片工作正常,但从图库中它不在这里是我的 Activity 结果中的代码。
//enter code here
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Uri selectedImageUri = null;
String filePath = null;
switch (requestCode) {
case PICK_IMAGE:
if (resultCode == Activity.RESULT_OK)
{
selectedImageUri = data.getData();
name = getPath(selectedImageUri);
}
break;
case PICK_Camera_IMAGE:
if (resultCode == RESULT_OK) {
//use imageUri here to access the image
selectedImageUri = imageUri;
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(this, "Picture was not taken", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Picture was not taken", Toast.LENGTH_SHORT).show();
}
break;
}
if(selectedImageUri != null)
{
try
{
// OI FILE Manager
String filemanagerstring = selectedImageUri.getPath();
// MEDIA GALLERY
String selectedImagePath = getPath(selectedImageUri);
if (selectedImagePath != null) {
filePath = selectedImagePath;
} else if (filemanagerstring != null) {
filePath = filemanagerstring;
} else {
Toast.makeText(getApplicationContext(), "Unknown path",
Toast.LENGTH_LONG).show();
Log.e("Bitmap", "Unknown path");
}
if (filePath != null)
{
decodeFile(filePath);
} else {
bitmap = null;
}
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(), "Internal error",
Toast.LENGTH_LONG).show();
Log.e(e.getClass().getName(), e.getMessage(), e);
}
}
}
public String getPath(Uri uri)
{
// just some safety built in
if( uri == null ) {
// TODO perform some logging or show user feedback
return null;
}
// try to retrieve the image from the media store first
// this will only work for images selected from gallery
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if( cursor != null ){
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
// this is our fallback here
return uri.getPath();
}
public void decodeFile(String filePath)
{
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 1024;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true)
{
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
bitmap = BitmapFactory.decodeFile(filePath, o2);
//imgView.setImageBitmap(bitmap);
}
如有任何帮助,我们将不胜感激。
最佳答案
在更高版本的 Android ( KitKat and above ) 中,从图库选择器返回的 Uri
的格式已经改变,并不总是可以从 Uri 获取文件路径
没有很多麻烦,有时根本不可能。因此,最好直接使用 Uri
解码位图。
更改您的 decodeFile() 函数以接受 Uri
并使用 BitmapFactory.decodeStream() 解码图像,像这样:
public void decodeFile(Uri fileUri)
{
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getContentResolver().openInputStream(fileUri), null, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 1024;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true)
{
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(fileUri), null, o2);
//imgView.setImageBitmap(bitmap);
}
然后您可以将您的 onActivityResult() 代码简化为:
if(selectedImageUri != null)
{
try
{
decodeFile(selectedImageUri);
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(), "Internal error",
Toast.LENGTH_LONG).show();
Log.e(e.getClass().getName(), e.getMessage(), e);
}
}
如果您在获取有效的 Uri
时遇到问题,请参阅 this question 的已接受答案了解如何在 OnActivityResult() 中获取 Uri
并具有 KitKat 及更高版本的正确权限。
关于android - 选择图像时无法解码流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28218419/