The problem: The exact same code works in Android 2.2, but not 4.0+.
The problem-tldr: I am able to analyze every frame of the camera preview in API level 8, but the callback to get frame data is never called in API level 14 and above.

The answer-tldr: Move mCamera.setPreviewCallback(new PreviewCallback()) from surfaceCreated() to surfaceChanged().
The answer-long:  (too burnt out to write it out)

The rest of the long story I may add in the future, but for now I just want to give a list of the API intricacies I learned on the way.

  • onPreviewFrameWithBuffer() will not be called if addCallbackBuffer(new byte[dataBufferSize]) doesn’t have a big enough buffer which is usually satisfied with int dataBufferSize= previewHeight * previewWidth * (ImageFormat.getBitsPerPixel(mCamera.getParameters().getPreviewFormat()) / 8);
  • “Not all devices have cameras that support preview sizes at the same aspect ratio as the device’s display.” – dev.android.com
  • After performing yuvimage.compressToJpeg(rect, 100, outstr) then Bitmap bmp = BitmapFactory.decodeByteArray(outstr.toByteArray(), 0, outstr.size()), the width and height of bitmap will not always be the same size as the rectangle rect.
  • Just a little arithmetic can slow cut your frames per second in a third.
  • There are many ways to display Android’s camera preview and get the data from it.
  • Even though all the samples you find are structured one way, the solution can be a way that hasn’t been documented.

 

..and more smaller lessons learned.

  • Danial Goodwin -

ps – I was going to put in a section for excuses, but I didn’t feel like it would contribute enough to readers.