I have an application to get camera preview frames with a surface. It was working on Android 4.0.4 but it does not work with Jelly Bean, 4.1.2 on the same device after the update. Simply, the callback is never called back. Here is the code: Snipped a little bit:
public class Panel extends Activity {
Camera myCamera;
int cameraId = -1;
MyCameraSurfaceView myCameraSurfaceView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_panel);
myCamera = getCameraInstance();
myCamera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.d("Camera Preview", data.length + "");
}
});
myCameraSurfaceView = new MyCameraSurfaceView(this, myCamera);
FrameLayout myCameraPreview = (FrameLayout) findViewById(R.id.videoview);
myCameraPreview.addView(myCameraSurfaceView);
}
private Camera getCameraInstance() {
Camera c = null;
try {
c = Camera.open();
} catch (Exception e) {
e.printStackTrace();
}
return c;
}
public class MyCameraSurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public MyCameraSurfaceView(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
}
}
}
}
The video frames are being displayed on the activity, so I cannot figure out what I am doing wrong.
I have rewrote the code by using another tutorial. It works, but now slower. I don't know the exact reason (it may be due to leaked N7000 ROM I use, it may have a bug or this is implemented differently in 4.1, not sure)
CameraPreview.java
public class CameraPreview implements SurfaceHolder.Callback,
Camera.PreviewCallback {
int PreviewSizeWidth;
int PreviewSizeHeight;
SurfaceHolder mSurfHolder;
Camera mCamera;
public CameraPreview(int PreviewlayoutWidth, int PreviewlayoutHeight) {
PreviewSizeWidth = PreviewlayoutWidth;
PreviewSizeHeight = PreviewlayoutHeight;
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Parameters p = camera.getParameters();
int width = p.getPreviewSize().width;
int height = p.getPreviewSize().height;
ByteArrayOutputStream outstr = new ByteArrayOutputStream();
Rect rect = new Rect(0, 0, width, height);
YuvImage yuvimage = new YuvImage(data, ImageFormat.NV21, width,
height, null);
yuvimage.compressToJpeg(rect, 80, outstr); // outstr contains image in jpeg
String encodedImage = Base64.encodeToString(
outstr.toByteArray(), Base64.DEFAULT); // this is base64 encoding of image
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
Parameters parameters;
mSurfHolder = arg0;
parameters = mCamera.getParameters();
parameters.setPreviewSize(PreviewSizeWidth, PreviewSizeHeight);
mCamera.setParameters(parameters);
mCamera.startPreview();
}
public void surfaceCreated(SurfaceHolder arg0) {
mCamera = Camera.open();
try {
// If did not set the SurfaceHolder, the preview area will be black.
mCamera.setPreviewDisplay(arg0);
mCamera.setPreviewCallback(this);
Parameters p = mCamera.getParameters();
p.setPreviewSize(PreviewSizeWidth, PreviewSizeHeight);
mCamera.setParameters(p);
} catch (IOException e) {
mCamera.release();
mCamera = null;
}
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
PanelActivity.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_panel);
SurfaceView camView = new SurfaceView(this);
SurfaceHolder camHolder = camView.getHolder();
int width = 352; // must set a compatible value, otherwise it gets the default width and height
int height = 288;
camPreview = new CameraPreview(width, height);
camHolder.addCallback(camPreview);
camHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mainLayout = (FrameLayout) findViewById(R.id.videoview);
mainLayout.addView(camView, new LayoutParams(width, height));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With