I'm doing one project with camera and after taking one photo camera freezes and u have to finish the activity and recall it again to take another photo, how can I take photo freeze for just 1-2 sec and then surface view to have the camera again. the same for video I am using media recorder, taking video press stop video saves and screen is still alive but I can not take video again I have to restart the activity?
Anybody have a solution?
I found a solution for this: After taking a picture, preview display will have stopped. To take more photos, call camera.startPreview() again first.
after capturing image you should stop the preview and start it back again.
mCamera.stopPreview();
mCamera.startPreview();
it would work fine.
Do any image processing in a background AsyncTask. This will allow your UI Activity to continue on and take another picture.
Edit: I cannot delete an accepted answer so please see stoefin's answer below. Calling camera.startPreview() before taking the next photo works for him.
The camera.startpreview(); answer didn't work for my case but the code below solved that problem for me and hope it helps others too.I used a thread to delay closing and opening of the camera after a photo is captured by 500ms
private void start_camera() {
try {
camera = Camera.open();
// camera.lock();
} catch (RuntimeException e) {
Log.e(tag, "init_camera: " + e);
return;
}
Camera.Parameters param = camera.getParameters();
param = camera.getParameters();
Camera.Size size = param.getSupportedPreviewSizes().get(0);
param.setPreviewSize(size.width, size.height);
camera.setParameters(param);
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewRunning = true;
} catch (Exception e) {
Log.e(tag, "init_camera: " + e);
return;
}}
private void captureImage() {
camera.takePicture(shutterCallback,null,jpegCallback);
Thread restart_preview=new Thread(){public void run(){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
camera.release();
camera=null;
start_camera();
}};
restart_preview.start();}
Instead of using the activities defined by the existing camera app on your phone, you can write your own Activity that uses the Camera API directly to accomplish the functionality you describe. The Camera class is documented here: http://developer.android.com/reference/android/hardware/Camera.html
The camera is freezing, because you are not restarting the preview of the camera, so restart it by calling camera.startpreview()
Related
So for my Android app, I have created a SurfaceView and assigned it as camera preview and start camera preview using the necessary API's. But now I want to turn the Flashlight ON (kind of act like a Torch) while the preview is working.
Please note that I have seen tons of examples online on how to turn flashlight on and it works as long as I don't call the open camera API. Below is the code -
try
{
CameraManager cameraManager = (CameraManager)context.GetSystemService(Context.CameraService);
if (cameraManager != null)
{
//for the sake of brevity, hardcoded the camera id. 0 is mostly back camera
cameraManager.SetTorchMode(0, true);
}
}
catch (CameraAccessException e)
{
LogUtil.Error("CameraInput", e.ToString());
}
Please note I am testing on Android N and hence the above code works flawlessly. But as soon as I call below line of code, the flash turns off.
Camera camera = Camera.Open(0);
// ...... some code ....//
camera.StartPreview();
When the above 2 lines execute, the flash goes off. Is this a know behaviour like where camera takes exclusive lock over flash hardware and resets it's value to default.
I tried reversing the above code i.e calling the Camera Open API being called first and then setting the flash. On that I get CameraAccessException , camera already in use.
What am i missing ?
Try this while previewing on SurfaceView
params = camera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_ON);
camera.setParameters(params);
Remember that If you want to use it as flashlight you can do:
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
If not, to turn flash on which will come out when you take the picture, you use:
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
Happy Coding!
Figured out how to torch on and off while camera is previewing. On button click to on/off the light, use this code:
//at some other function where camera is initialised and start preview
//...
Camera camera = Camera.open();
camera.startPreview();
//...
boolean lightOn = false;
//...
buttonLight.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Camera.Parameters p = camera.getParameters();
if (!lightOn) {
lightOn = true;
p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
camera.setParameters(p);
} else {
lightOn = false;
p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(p);
}
}
});
Happy Coding! :D
I've searched all over on the web and I can't find out what that 1001 error is. A few seconds after that I get the camera 100 error but I can't find out what the first error is. Does anyone have any ideas?
I encountered this error as well on my S3. I believe I tracked it down to how the camera preview surface was used by the MediaRecorder. In my case the preview display was getting reset when I was attempting to start recording. I solved it by cleaning out my code and just used the calls to set, start and stop the preview display in the SurfaceView implementation below (from the Android Camera developer guide):
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
Just thought I would add a post here for future reference. This issue bothered me for a long time.
It turns out that my problem was caused by an incorrect preview size, although the resolution set was obtained from the getSupportedPictureSize method.
So for example you can get the sizes as follows:
//first entry in list is 1392x1392 for front facing camera on an S3
List<Camera.Size> supportedPictureSizes = params.getSupportedPictureSizes();
Setting this resolution or neglecting to set a picture size alltogether will cause the dreaded error 1001.
If you encounter this on any other device I would recommend trying different picture sizes.
So there was another reason for why I got it on my Galaxy S3. I was using a TextureView to show my camera preview and got this dreaded error when pressing the home button after a successful preview and then entering the app again. In the onResume() function I started up the preview again and found that I had not released the SurfaceTexture instance variable in the onSurfaceTextureDestroyed() function.
I added the release line to this function and it now looks like this and works perfectly:
#Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
mSurfaceTexture = null; //This was the offending culprit.
releaseMediaPlayer();
releaseVideoRecorder();
releaseCamera();
return false;
}
In my case, in Samsung S3, the video-size parameter was not set and this led to the 1001 error. Setting the video size on the media recorder using preview size fixed the issue. However, this change may fail on other devices since the parameter may or may not be available/set in all devices. The following code addresses most of the devices:
if(params.get("video-size") != null && params.get("video-size").isEmpty()) {
int videoWidth = params.getPreviewSize().width;
int videoHeight = params.getPreviewSize().height;
mediaRecorder.setVideoSize(videoWidth, videoHeight);
} else {
mediaRecorder.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
}
I want to capture images through Intent
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE)
but the problem is that with this code the camera is started and the user has to click on the camera button to capture the image , but what i want is that the camera sholud start and take picture without any furthur interaction with the user
I want to do this using INTENT
That is the way I did it :
Declare an instance of Camera, and SurfaceHolder.
Create an Object CallBackPicture, and implements the method on PictureTaken (method launched when you want to take a picture)
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Camera.PictureCallback mCall = new Camera.PictureCallback()
{
#Override
public void onPictureTaken(byte[] data, Camera camera)
{
//DO YOUR STUFF
}
};
// Open the instance of camera
mCamera = Camera.open();
try {
// Call the preview (not sure if it is working without this call
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(mCamera == null) Log.i(TAG, "mCamera is null");
// Will call the onPictureTaken implemented above
// Look at the documentation : public final void takePicture
mCamera.takePicture(null, null, mCall);
mCamera.stopPreview();
mCamera.release();
By modifying this, you should be able to do what you want..
Don't forget to modify the Manifest.XML too, but I think you've already done it!
EDIT : sometimes there is some problem with stoppreview() and release()..
So, the thing i've done is :
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
mCamera = Camera.open();
etc...
This can't be done. There are only two options:
Invoking Camera app via Intent. The user then uses Camera app in normal way - i.e. presses the button when ready.
Use Camera class - this is much more work compared to running Camera app via Intent. But it gives you full control.
When you call the camera intent you basically "run" the camera app (or other app that registered on this intent), so basically, you can't control of how it works.
You can use the Camera API...take a look here
when using the Camera.PreviewCallback implementation the onPreviewFrame is called without problem after initializing camera and starting preview (Camera.startPrevew()). The problem is if I make a video recording using MediaRecorder onPreviewFrame does not get called any more.
I understand that when using MediaRecorder to record video stops the Camera.PreviewCallback, but why can't it be restarted?
I have tried resetting the camera preview callback (setPreviewCallback(callback)) and restarting startPreview, but while I have a preview there is no call to onPreviewFrame.
You must call setPreviewCallback in the surfaceChanged method, not only in the surfaceCreated.
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mHolder.getSurface() == null){
return;
}
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
try {
mCamera.setPreviewCallback(this);
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
I had a similar problem; see
setOneShotPreviewCallback not hitting onPreviewFrame() in callback
What I discovered was that after calling Camera#unlock() to prepare the MediaRecorder, it was necessary to call Camera#reconnect() before setting the preview callback. This is because Camera.unlock() detaches the camera from the process to let the MediaRecorder connect to it.
http://developer.android.com/reference/android/hardware/Camera.html#unlock()
In my investigations I also discovered that if you set any preview callbacks using other methods than the one shot method, you have to reset all of these after calling Camera#reconnect() as well. So, briefly:
mCamera.unlock();
//set up MediaRecorder
mCamera.reconnect();
mCamera.setPreviewCallback(mCallback);
//or whatever callback method you want to use
//and even if you've set this callback already
I hope that helps!
You should call it within new instantiation of previewCallBacks() interface, like below
public void surfaceCreated(SurfaceHolder holder) {
// if (mediaRecorder == null) {
try {
camera = Camera.open();
camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] _data, Camera _camera) {
}
}
}
}
You need to call startPreview() again after a video or photo was taken.
I am developing on/for a Samsung Galaxy Tab (7inches). My application has to be in portrait mode only, i.e i have locked it to portrait mode in my application and in the device settings. The problem is when i try to rotate the camera preview, it is currently rotated 90 degrees in the wrong direction.
Right now this is my surfaceCreated
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
try {
camera.setPreviewDisplay(holder);
Camera.Parameters parameters = camera.getParameters();
parameters.setPictureFormat(PixelFormat.JPEG);
parameters.set("orientation", "portrait");
//camera.setDisplayOrientation(90);
parameters.setRotation(90);
camera.setParameters(parameters);
}
catch (IOException exception) {
camera.release();
}
}
The camera.setDisplayOrientation(90) does not seem to be working (it does nothing, which is why i have commented it away). However the parameters.setRotation(90) DOES IN FACT GET THE JOB DONE! but it creates an ugly "stripe" of "flickering colors" along the side of the application. setDisplayOrientation() should work for me, since i am running android api 8 (Froyo 2.2)!!
There is a thread on google about problems pertaining to rotational issues http://code.google.com/p/android/issues/detail?id=1193#c26, but to the best of my knowledge it does not suggest anything for my problem.
Any and all solutions pertaining to this problem will be greatly appreciated! thanks!
This worked for me in Samsung Galaxy tab:
public void surfaceCreated(SurfaceHolder holder)
{
// The Surface has been created, acquire the camera and tell it where to draw.
mCamera = Camera.open();
Parameters params = mCamera.getParameters();
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
{
params.set("orientation", "portrait");
mCamera.setDisplayOrientation(90);
}
try
{
mCamera.setPreviewDisplay(holder);
}
catch (IOException exception)
{
mCamera.release();
mCamera = null;
}
}
If your application is designed to only take Portrait photos, then the simplest thing to do is to just rotate the image data after you've taken the photo, and not worry about the camera settings. I'm not sure if the Tab is buggy (I've never tried to rotate the camera preview) but rotating the image after you've taken the shot is very simple... the problem is only if you need to know which way the device was being held when the picture was taken. If that's not a concern for you, then don't fret over it :)
try this. I make this code and test on Galaxy Tab. The code works well
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
try {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO)
{
camera.setDisplayOrientation(90);
} else {
Parameters parameters = camera.getParameters();
parameters.setRotation(90);
camera.setParameters(parameters);
}
camera.setPreviewDisplay(holder);
} catch (IOException exception) {
camera.release();
}
}