Android BitmapFactory.decodeFile返回null

时间:2016-04-21 15:59:36

标签: android android-permissions

我调用Activity.requestPermissions(READ_EXTERNAL_STORAGE)并在用户单击ALLOW后尝试使用BitmapFactory.decodeFile(path)但它返回null。如果已经授予所有权限,则可以。怎么了?

ImageChooser类

public class ImageChooser {

    private final static int GET_IMAGE_REQUEST = 1;

    private final static int PERMISSIONS_REQUEST = 2;

    public interface Callback {
        void onImageChosen(Bitmap image);
    }

    private Activity activity;
    private Fragment fragment;
    private Callback callback;

    private String capturedImagePath;

    public ImageChooser(Activity activity, Fragment fragment, Callback callback) {
        this.activity = activity;
        this.fragment = fragment;
        this.callback = callback;
    }

    public void choose() {
        boolean readStorageGranted = PermissionsManager
                .isPermissionGrantedReal(activity, Permission.READ_EXTERNAL_STORAGE);
        boolean cameraGranted = PermissionsManager
                .isPermissionGrantedReal(activity, Permission.CAMERA);

        if (readStorageGranted && cameraGranted) {
            chooseImage();
        } else {
            fragment.requestPermissions(new String[] {
                    Permission.CAMERA.permission,
                    Permission.READ_EXTERNAL_STORAGE.permission
            },  PERMISSIONS_REQUEST);
        }
    }

    private void chooseImage() {
        Intent pickIntent = new Intent(Intent.ACTION_PICK);
        pickIntent.setType("image/*");

        String filename = "image.png";
        String dir = activity.getExternalCacheDir().getAbsolutePath();

        capturedImagePath = dir + "/" + filename;
        File file = new File(capturedImagePath);

        Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));

        Intent chooserIntent = Intent.createChooser(pickIntent,
                activity.getString(R.string.take_choose_photo));

        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { captureIntent });

        fragment.startActivityForResult(chooserIntent, GET_IMAGE_REQUEST);
    }

    public void handleOnActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == GET_IMAGE_REQUEST && resultCode == Activity.RESULT_OK) {
            Bitmap image = null;

            String picturePath = null;

            if (data == null) { // From Camera.
                File imageFile = new File(capturedImagePath);
                if (imageFile.exists()) {
                    image = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
                }
            } else { // From Gallery.
                Uri selectedImage = data.getData();

                String[] filePathColumn = { MediaStore.Images.Media.DATA };

                Cursor cursor = activity.getContentResolver().query(selectedImage, filePathColumn,
                        null, null, null);

                if (cursor != null) {
                    cursor.moveToFirst();

                    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                    picturePath = cursor.getString(columnIndex);
                    cursor.close();

                    image = BitmapFactory.decodeFile(picturePath);
                }
            }

            if (image != null) {
                callback.onImageChosen(image);

            }
        }
    }

    public void handleOnRequestPermissionsResult(int requestCode, String[] permissions,
                                                 int[] grantResults) {
        if (grantResults.length > 0 &&
                grantResults[0] == PackageManager.PERMISSION_GRANTED &&
                grantResults[1] == PackageManager.PERMISSION_GRANTED) {

            chooseImage();
        }
    }
}

使用

的示例
public class CustomizeFragment extends Fragment {

    @Bind(R.id.add_image)
    View addImageView;

    @Bind(R.id.switch_button_off)
    Button switchOffButton;

    @Bind(R.id.switch_button_on)
    Button switchOnButton;

    @Bind(R.id.mb_image)
    RoundedImageView imageView;

    private ImageChooser imageChooser;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_customize, container, false);

        ButterKnife.bind(this, v);

        return v;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        imageChooser = new ImageChooser(getActivity(), this, image -> {
            addImageView.setVisibility(View.GONE);
            imageView.setVisibility(View.VISIBLE);

            imageView.setImageBitmap(image);
        });
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();

        ButterKnife.unbind(this);
    }

    @OnClick({R.id.add_image, R.id.mb_image})
    void onAddImageClick() {
        imageChooser.choose();
    }


    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        imageChooser.handleOnActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        imageChooser.handleOnRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

1 个答案:

答案 0 :(得分:1)

主要是BitmapFactory.decodeFile()返回null是.jpg图像具有这样的分辨率,使得它的Bitmap需要比操作系统可以提供更多的内存。尝试缩小它。