Reputation: 205
I want to capture a photo manually not by using existing camera apps. So i made this Activity:
public class CameraActivity extends Activity {
private Camera mCamera;
private Preview mPreview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
// Create an instance of Camera
mCamera = Camera.open(0); if(mCamera !=null) Log.i("CameraActivity.onCreate()", "mCamera initialized");
// Create our Preview view and set it as the content of our activity.
mPreview = new Preview(this); if(mPreview !=null) Log.i("CameraActivity.onCreate()", "mPreview initialized");
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview); Log.i("CameraActivity.onCreate()", "mPreview added to FrameLayout");
mPreview.setCamera(mCamera); Log.i("CameraActivity.onCreate()", "mPreview.setCamera(mCamera)");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_camera, menu);
return true;
}
@Override
public void onPause() {
super.onPause();
mPreview.stopPreviewAndFreeCamera();
}
}
This is the CameraPreview which i want to use:
public class Preview extends ViewGroup implements SurfaceHolder.Callback {
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
private Camera mCamera;
List<Size> mSupportedPreviewSizes;
/**
* @param context
*/
public Preview(Context context) {
super(context);
mSurfaceView = new SurfaceView(context); Log.i("CameraPreview.constructor(...)", "mSurfaceView initialized");
if(mSurfaceView==null) {Log.i("CameraPreview.constructor(...)", "mSurfaceView is null");}
addView(mSurfaceView);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = mSurfaceView.getHolder(); Log.i("CameraPreview.constructor(...)", "mHolder setup");
if(mHolder==null) {Log.e("PreviewCamera", "mHolder is null");}
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
/**
* @param context
* @param attrs
*/
public Preview(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
/**
* @param context
* @param attrs
* @param defStyle
*/
public Preview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
/* (non-Javadoc)
* @see android.view.ViewGroup#onLayout(boolean, int, int, int, int)
*/
@Override
protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
// TODO Auto-generated method stub
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(width, height);
requestLayout();
mCamera.setParameters(parameters);
/*
Important: Call startPreview() to start updating the preview surface. Preview must be
started before you can take a picture.
*/
mCamera.startPreview(); Log.i("CameraPreview.surfaceChanged(...)", "mCamera.startPreview()");
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
if (mCamera != null) {
/*
Call stopPreview() to stop updating the preview surface.
*/
mCamera.stopPreview(); Log.i("CameraPreview.surfaceDestroyed(...)", "mCamera.stopPreview()");
}
}
/**
* When this function returns, mCamera will be null.
*/
public void stopPreviewAndFreeCamera() {
if (mCamera != null) {
/*
Call stopPreview() to stop updating the preview surface.
*/
mCamera.stopPreview(); Log.i("CameraPreview.stopPreviewAndFreeCamera()", "mCamera.stopPreview()");
/*
Important: Call release() to release the camera for use by other applications.
Applications should release the camera immediately in onPause() (and re-open() it in
onResume()).
*/
mCamera.release(); Log.i("CameraPreview.stopPreviewAndFreeCamera()", "mCamera.release()");
mCamera = null;
}
}
/***
*
* @param camera
*/
public void setCamera(Camera camera) {
if (mCamera == camera) { Log.i("CameraPreview.setCamera()", "mCamera equals the Camera you want to set"); return; }
stopPreviewAndFreeCamera(); Log.i("CameraPreview.setCamera()", "stopPreviewAndFreeCamera()");
mCamera = camera; Log.i("CameraPreview.setCamera()", "setup new Camera");
if (mCamera != null) {
List<Size> localSizes = mCamera.getParameters().getSupportedPreviewSizes();
mSupportedPreviewSizes = localSizes;
requestLayout();
try {
mCamera.setPreviewDisplay(mHolder);
Log.i("CameraPreview.setCamera()", "mCamera.setPreviewDisplay(mHolder)");
} catch (IOException e) {
e.printStackTrace();
}
/*
Important: Call startPreview() to start updating the preview surface. Preview must
be started before you can take a picture.
*/
mCamera.startPreview(); Log.i("CameraPreview.setCamera()", "mCamera.startPreview()");
}
}
/***
*
* @param id
* @return
*/
public boolean safeCameraOpen(int id) {
boolean qOpened = false;
try {
releaseCameraAndPreview();
mCamera = Camera.open(id);
qOpened = (mCamera != null);
} catch (Exception e) {
// Log.e(R.string.app_name, "failed to open Camera");
e.printStackTrace();
}
return qOpened;
}
/**
*
*/
Camera.PictureCallback mPicCallback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
Log.d("lala", "pic is taken");
}
};
/**
*
*/
public void takePic() {
// mCamera.takePicture(null, mPicCallback, mPicCallback);
}
/**
*
*/
private void releaseCameraAndPreview() {
this.setCamera(null);
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
}
This is the Layout of CameraActivity:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CameraActivity" >
<FrameLayout
android:id="@+id/camera_preview"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="1"
/>
<Button
android:id="@+id/button_capture"
android:text="Capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>
But when i start the CameraActivity, i just see a blank white background and the Capture-Button??? Why i dont see the Camera-Screen?
EDIT: Logcat:
12-16 13:09:39.941: I/CameraActivity.onCreate()(439): mCamera initialized
12-16 13:09:39.941: I/CameraPreview.constructor(...)(439): mSurfaceView initialized
12-16 13:09:39.941: I/CameraPreview.constructor(...)(439): mHolder setup
12-16 13:09:39.941: I/CameraActivity.onCreate()(439): mPreview initialized
12-16 13:09:39.952: I/CameraActivity.onCreate()(439): mPreview added to FrameLayout
12-16 13:09:39.952: I/CameraPreview.setCamera()(439): stopPreviewAndFreeCamera()
12-16 13:09:39.952: I/CameraPreview.setCamera()(439): setup new Camera
12-16 13:09:39.961: D/Camera(439): app passed NULL surface
12-16 13:09:39.961: I/CameraPreview.setCamera()(439): mCamera.setPreviewDisplay(mHolder)
12-16 13:09:39.971: I/CameraPreview.setCamera()(439): mCamera.startPreview()
12-16 13:09:39.971: I/CameraActivity.onCreate()(439): mPreview.setCamera(mCamera)
12-16 13:09:40.622: I/ActivityManager(60): Displayed com.example.popup/.CameraActivity: +810ms
Upvotes: 2
Views: 6977
Reputation: 2666
It looks like the OP followed the 'Controlling the camera' tutorial from http://developer.android.com/training/camera/cameradirect.html. I tried the same, but soon found out that this tutorial doesn't work.
To save other beginners the same frustration of trying to get the tutorial to work, here's another tutorial which does work: http://www.tutorialspoint.com/android/android_camera.htm.
Upvotes: 0
Reputation: 3294
You can check whether the layout_width and layout_height properties of Preview is set to match_parent.
Upvotes: 0
Reputation: 1
I was having same problem. Then I extended it to SurfaceView instead of ViewGroup. And in a magical moment it worked...
Upvotes: 0
Reputation: 250
I think you should call open()
method after addView()
.
Camera preview size is set by addView()
.
Upvotes: 2
Reputation: 1533
You aren't calling setCamera with the camera (only null), so you never set the preview display.
Upvotes: 0