Android ImageReader.acquireLatestImage retourne invalide JPG

Je suis en utilisant Android ImageReader classe pour recevoir des Bitmaps de MediaProjection.createVirtualDisplay méthode.

Mon code ressemble tellement loin de cela:

mProjection.createVirtualDisplay("test", width, height, density, flags, mImageReader.getSurface(), new VirtualDisplayCallback(), mHandler);
            mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
                @Override
                public void onImageAvailable(ImageReader reader) {
                    Image image = null;
                    try {
                        image = mImageReader.acquireLatestImage();
                        final Image.Plane[] planes = image.getPlanes();
                        final ByteBuffer buffer = planes[0].getBuffer();
                        final byte[] data = new byte[buffer.capacity()];
                        buffer.get(data);
                        final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                        if (bitmap==null)
                            Log.e(TAG, "bitmap is null");

                    } catch (Exception e) {
                        if (image!=null)
                            image.close();
                    }
                }

            }, mHandler);

Le problème est que BitmapFactory ne peut pas décoder des données[] retour à la Bitmap, c'est à dire BitmapFactory renvoie toujours null. Les seuls messages je vois de logcat viennent de android_media_ImageReader.cpp et comme ça:

D/ImageReader_JNI(1432): ImageReader_imageSetup: Receiving JPEG in HAL_PIXEL_FORMAT_RGBA_8888 buffer.
W/ImageReader_JNI(1432): Image_getJpegSize: No JPEG header detected, defaulting to size=width=3891200

Image de l'objet renvoyé par acquireLatestImage n'est pas nul, mais pas valide en JPEG, j'ai essayé de vérifier avec le test suivant qui échoue:

if((buf [0] & 0xFF) == 0xFF && (buf[1] & 0xFF) == 0xD8 && (buf[2] & 0xFF) == 0xFF && (buf[3] & 0xFF) == 0xE0)
    Log.e(TAG, "is JPG");
else
    Log.e(TAG, "not a valid JPG");

La seule chose que je suis se douter à ce moment est que Android 5.0 émulateur je suis en train de tester contre ne peut pas hanlde les appels d'API.

Des idées?

Il y a quelques bonnes réponses ci-dessous qui résoudre votre problème. Veuillez en choisir une comme a accepté de répondre afin que d'autres personnes puissent en bénéficier.

OriginalL'auteur mtsahakis | 2014-10-31