Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android camera2: java.lang.IllegalStateException: maxImages (1) has already been acquired, call #close before acquiring more

Hello having trouble to fix this issue.

I already have a imageReader.close called inside the ImageAvailable callback but still having the error:

java.lang.IllegalStateException: maxImages (1) has already been acquired, call #close before acquiring more.

Code I have is here:

private ImageReader.OnImageAvailableListener imageAvailableListener = new ImageReader.OnImageAvailableListener()
{
    @Override
    public void onImageAvailable(ImageReader reader) {
        Image img = mReader.acquireLatestImage();

        mReader.close();
    }

};

ps. I also use the argument reader as well but not seem to solve the problem

like image 342
LittleFunny Avatar asked Sep 12 '15 06:09

LittleFunny


3 Answers

Ok I have solved my problem. I need to close the img object not the ImageReader.

like image 167
LittleFunny Avatar answered Oct 21 '22 12:10

LittleFunny


    private ImageReader.OnImageAvailableListener imageAvailableListener = new ImageReader.OnImageAvailableListener() {
    @Override
    public void onImageAvailable(ImageReader reader) {
        String status = Environment.getExternalStorageState();
        if (!status.equals(Environment.MEDIA_MOUNTED)) {
            Toast.makeText(getApplicationContext(), "your SD card is not available", Toast.LENGTH_SHORT).show();
            return;
        }
        Image image = reader.acquireNextImage();
        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
        byte[] data = new byte[buffer.remaining()];
        buffer.get(data);
        image.close();//after you use the image's content ,you can close it
        String filePath = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/";
        String picturePath = System.currentTimeMillis() + ".jpg";
        imgFile = new File(filePath, picturePath);
        Uri uri = Uri.fromFile(imgFile);
        try {//Store to folder
            FileOutputStream fileOutputStream = new FileOutputStream(imgFile);
            fileOutputStream.write(data);
            fileOutputStream.close();


        } catch (IOException e) {
            e.printStackTrace();
        }
        startEditPictureActivity(uri, imgFile);


    }
};
like image 3
xiaoshuang tong Avatar answered Oct 21 '22 11:10

xiaoshuang tong


close() needs to be called on the Image object that acquireLatestImage() returns.

So, going from the OP's implementation of onImageAvailable() in his sample, just adding .close() after the acquireLatestImage() should do the trick.
Like so:

public void onImageAvailable(ImageReader reader) {
    Image image = reader.acquireLatestImage().close(); // Note the added `close()` call.
}

I should also add that the image will no longer be usable after you call close() on it (see docs).
So the solution I've mentioned above will get you rid off the exception OP mentioned, but you also won't be able to do anything with the image. This is obviously easy to fix by first doing whatever you want with the image and only then calling close() on it.

like image 1
user2347921 Avatar answered Oct 21 '22 10:10

user2347921