Search code examples
javaandroidbitmapfactory

Android; BitmapFactory.decodeFile(file) returns null, file is known to exists


I am attempting to render a photo I have taken with the following class, which returns the used file:

public File takePhoto(){
    Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    File destination= null;
    try {
        destination = createFile();
    } catch (IOException error) {
        Log.v(TAG, "IO error, reading exception");
        String errorMessage = error.getMessage();
        Log.v(TAG, errorMessage);
        String errorCauseMessage = error.getCause().getMessage();
       Log.v(TAG, errorCauseMessage);
    }
    if (destination != null){
        Log.v(TAG, "destination was written");
        pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(destination));
        parentActivity.startActivityForResult(pictureIntent, REQUEST_TAKE_PHOTO);
        Log.v(TAG, "destination was: " + destination.getAbsolutePath());
    }
    else {
        Log.v(TAG, "destination was not written");
    }``
    return destination;

The result is then used in the following code:

Log.v(TAG, "adding picture");
            PhotoHandler photoHandler = new PhotoHandler(getPackageManager(), PolishCreateActivity.this);
            File imgFile = photoHandler.takePhoto();
            if (imgFile == null) {
                Toast.makeText(this, ERROR_TOAST_TEXT, Toast.LENGTH_SHORT).show();
            } else {
                Log.v(TAG, "Picture added");

                Log.v(TAG, "storing directory");
                img = imgFile.getAbsolutePath();
                Log.v(TAG, "Directory stored");

                Log.v(TAG, "Displaying picture");
                LinearLayout layout = (LinearLayout) findViewById(R.id.rootLayout);
                if (imageViewExists == Boolean.TRUE) {
                    ImageView oldView = (ImageView) findViewById(R.id.imageViewID);
                    layout.removeView(oldView);
                }
                UIHelper uiHelper = new UIHelper(this.getApplicationContext());
                ImageView imageView = uiHelper.getImageViewFromPath(imgFile);
                imageView.setId(R.id.imageViewID);
                layout.addView(imageView);
                imageViewExists = Boolean.TRUE;
                Log.v(TAG, "picture displayed");

And passed to this method, as imgFile:

public ImageView getImageViewFromPath(File imgFile) {
    ImageView imageView = new ImageView(context);
    Bitmap imgBM = null;
    if (imgFile.exists()) {
        Log.v(TAG, "image file exists");
        imgBM = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
        if (imgBM == null){
            Log.v(TAG, "Bitmap returned was null");
        }
    }
    imageView.setImageBitmap(imgBM);
    imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
    Log.v(TAG, "ImageView was created");
    return imageView;
}

The problem is that BitmapFactory.decodeFile(imgFile.getAbsolutePath) returns every time I run it, even though the file exists (I can tell because I'm getting the log messages in the "if (imgFile.exists())" body). I have searched for a solution for a long time, but I have not found a solution. I have tested that it is not causing an outOfMemory exception, which it is not. Any help would be appreciated.


Solution

  • takePhoto starts an activity for a result:

    parentActivity.startActivityForResult(pictureIntent, REQUEST_TAKE_PHOTO);
    

    But your code carries on like this was done instantly, which it is not. The file will of course be there, but it will always be 0 bytes large.

    You will need to override onActivityResult() and handle the file contents from there.