Java BitmapFactory 无法解码流

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21195899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 07:14:34  来源:igfitidea点击:

BitmapFactory Unable to decode stream

javaandroidimage

提问by Lion789

Hey I am not sure why this keeps coming up every time I select an image in my gallery?

嘿,我不知道为什么每次我在画廊中选择图像时都会出现这种情况?

Here is the code:

这是代码:

if (v == uploadImageButton) {
                        // below allows you to open the phones gallery
                        Intent intent = new Intent();
                        intent.setType("image/*");
                        intent.setAction(Intent.ACTION_GET_CONTENT);
                        startActivityForResult(
                                        Intent.createChooser(intent, "Complete action using"), 1);
                }


public void onActivityResult(int requestCode, int resultCode, Intent data) {
                if (resultCode == RESULT_OK && requestCode == 1 && null != data) {
                        // Bitmap photo = (Bitmap) data.getData().getPath();
                        Uri selectedImageUri = data.getData();
                        String[] filePathColumn = { MediaStore.Images.Media.DATA };

                        Cursor cursor = getContentResolver().query(selectedImageUri,
                                        filePathColumn, null, null, null);
                        cursor.moveToFirst();

                        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                        String picturePath = cursor.getString(columnIndex);
                        cursor.close();
                        Log.e("Picture", picturePath);
                        decodeFile(picturePath);
                }
        }


public void decodeFile(String filePath) {
                // TODO Auto-generated method stub
                // 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 bitmap = BitmapFactory.decodeFile(filePath, o2);

                imageview.setImageBitmap(bitmap);
        }

Error:

错误:

01-17 23:18:04.642: D/Documents(25157): onFinished() [content://com.android.providers.media.documents/document/image%3A901]
01-17 23:18:04.682: E/BitmapFactory(24993): Unable to decode stream: java.lang.NullPointerException
01-17 23:18:04.682: E/BitmapFactory(24993): Unable to decode stream: java.lang.NullPointerException
01-17 23:18:09.732: I/InputReader(766): Reconfiguring input devices.  changes=0x00000004
01-17 23:18:09.732: I/InputReader(766): Device reconfigured: id=4, name='touch_dev', size 1080x1920, orientation 3, mode 1, display id 0

采纳答案by zapl

Don't assume that there is a file path. Android 4.4 and up are about to remove them. And the uri you got has already no path.

不要假设有文件路径。Android 4.4 及更高版本即将删除它们。你得到的uri已经没有路径了。

You can still access the file content either through an InputStream(ContentResolver#openInputStream(Uri uri)) or through a file descriptor.

您仍然可以通过InputStream( ContentResolver#openInputStream(Uri uri)) 或文件描述符访问文件内容。

It's explained here: ContentProviders: Open a document(scroll down, link to section seems to be broken)

解释如下:ContentProviders:打开一个文档(向下滚动,部分链接似乎已损坏)

And that does work on older android versions too.

这也适用于较旧的 android 版本。

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK && requestCode == 1 && null != data) {
        decodeUri(data.getData());
    }
}

public void decodeUri(Uri uri) {
    ParcelFileDescriptor parcelFD = null;
    try {
        parcelFD = getContentResolver().openFileDescriptor(uri, "r");
        FileDescriptor imageSource = parcelFD.getFileDescriptor();

        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeFileDescriptor(imageSource, 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 bitmap = BitmapFactory.decodeFileDescriptor(imageSource, null, o2);

        imageview.setImageBitmap(bitmap);

    } catch (FileNotFoundException e) {
        // handle errors
    } catch (IOException e) {
        // handle errors
    } finally {
        if (parcelFD != null)
            try {
                parcelFD.close();
            } catch (IOException e) {
                // ignored
            }
    }
}