Method Camera.takePicture() crash on Nexus 5, but Xperia mini is OK - android

At first please excuse my bad English.
I have problem with programmatically taking photo. I wrote an app, that makes collection of photos based on countdown timer and after that, photos are being processed using c++ code.
I'm using dummy SurfaceView, because I don't need preview in UI. The code below is working on my phone Xperia mini - API 15 (so permissions and code would be correct), but I borrowed school Nexus 5 - API 21 and there is problem with preview.
takePicture: camera 0: Cannot take picture without preview enabled
I found a solution, which uses setPreviewTexture (commented below) instead of setPreviewDisplay. It working for the first photo, which is normally saved, but I get the same error after the second call of takePicture().
Thanks for every advice, LS
Camera camera;
#Override
protected void onResume() {
super.onResume();
// is camera on device?
if(!checkCameraHardware()) return;
releaseCamera();
try {
camera.stopPreview();
} catch (Exception e){
Log.d(TAG, "No preview before.");
}
SurfaceView dummy = new SurfaceView(this);
camera = Camera.open();
Camera.Parameters params = camera.getParameters();
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
camera.setParameters(params);
try {
//camera.setPreviewTexture(new SurfaceTexture(10));
camera.setPreviewDisplay(dummy.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
camera.startPreview();
}
SOLUTION:
I needed to refresh preview. The code below is working on Xperie and Nexus too.
Question remains why I have to use setPreviewTexture, because setPreviewDisplay always returns error on Nexus.
camera.takePicture(null, null, new PictureCallback() {
#Override
public void onPictureTaken(final byte[] data, Camera camera) {
// save picture
refreshPreview();
}
});
public void refreshPreview() {
try {
camera.stopPreview();
} catch (Exception e) {}
try {
camera.startPreview();
} catch (Exception e) {}
}
and in function onResume()
try {
camera.setPreviewTexture(new SurfaceTexture(10));
} catch (IOException e) {}

Just add a callback for starting preview on your camera instance. The thing is that after starting preview on camera instance, it needs some time to be able take a picture. Try this:
camera.startPreview();
camera.setOneShotPreviewCallback(new Camera.PreviewCallback() {
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
camera.takePicture(null, null, new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// do something you want with your picture and stop preview
camera.stopPreview();
}
});

Once the picture is taken, refresh you're surfaceview & stop the preview and releasee camera and restart the process again.
try {
camera.takePicture(null, null, new PictureCallback() {
public void onPictureTaken(final byte[] data, Camera camera) {
//once ur logic done
refreshCamera();
}
});
} catch (Exception e2) {
// Toast.makeText(getApplicationContext(), "Picture not taken", Toast.LENGTH_SHORT).show();
e2.printStackTrace();
}
public void refreshCamera() {
if (dummy.getHolder().getSurface() == null) {
return;
}
try {
camera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
try {
camera.setPreviewDisplay(dummy.getHolder());
camera.startPreview();
} catch (Exception e) {
}
}
Hope this solution may help you.

Related

Open camera inside fragment

Is it possible to use camera in fragment like view, so that it wouldn't open another app and go away from my special app?
I want something like SurfaceView with camera?
Yes it is, Check this link .
Basically overwritting the SurfaceView and integrating the camera picture callback.
example code :
/* Surface on which the camera projects it's capture results.
*/
class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
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) {
e.printStackTrace();
}
}
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){
e.printStackTrace();
}
}
}
with a camera picture callback like:
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null){
Toast.makeText(getActivity(), "Image retrieval failed.", Toast.LENGTH_SHORT)
.show();
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
};
Native implementation is way better.
XML
<com.google.android.cameraview.CameraView
android:id="#+id/camera"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:keepScreenOn="true"
android:adjustViewBounds="true"
app:autoFocus="true"
app:aspectRatio="4:3"
app:facing="back"
app:flash="auto"/>
Inside Activity/Fragment
Start camera
mCameraView.start();
Stop camera
mCameraView.stop();
Open source: Google
Requires API Level 9. The library uses Camera 1 API on API Level 9-20 and Camera2 on 21 and above.

Capture Image programmatically in android

how i can Using camera to capture picture programmatically without touch the capture button in android like selfie stick using bluetooth sign.
Try something like this:
public void takePictureNoPreview(Context context){
// open back facing camera by default
Camera myCamera=Camera.open();
if(myCamera!=null){
try{
//set camera parameters if you want to
//...
// here, the unused surface view and holder
SurfaceView dummy=new SurfaceView(context)
myCamera.setPreviewDisplay(dummy.getHolder());
myCamera.startPreview();
myCamera.takePicture(null, null, getJpegCallback()):
} finally {
myCamera.close();
}
} else {
//booo, failed!
}
private PictureCallback getJpegCallback(){
PictureCallback jpeg=new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream fos;
try {
fos = new FileOutputStream("test.jpeg");
fos.write(data);
fos.close();
} catch (IOException e) {
//do something about it
}
}
};
}
}
Or try some solutions from this post: Taking pictures with camera on Android programmatically

Camera frozen after capture, OnpictureTaken method never called

I am working on an application which uses the camera to capture images. I am using callback methods for capture. It's working normally in all devices except "Huawei MediaPad 7inch",which has android 4.0.3. When i am launching my camera, after capturing image the camera freezes and OnPicturetaken method never called. In log cat I got the camera error "E/Camera(4562): Error -2147483648" Please help.
Here is my code.
public void takePicture() {
try {
Camera.PictureCallback mPictureCallbackRaw = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera c) {
/** Do nothing */
}
};
Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback() {
public void onShutter() {
/** Do nothing */
}
};
mPreview.mCamera.takePicture(mShutterCallback, mPictureCallbackRaw, this);
} catch (Exception ex) {
NGAndroidUtil.logErr("[CameraPreview] takePicture exception", ex.getMessage(), ex);
}
}

Android Camera - Sometimes when i take photos, the app freezes and the camera is non-usable

I have built an application which takes photos when you touch the preview.
I can take many photos, but sometimes when i touch the preview to take a photo, there is no shutter sound and the whole application freezes. Moreover, after that, if i try to launch launch the built-in camera application, i get a message that the camera can't be used.
I don't know the reason for that behavior, it happens randomly and when it happens i must restart the device (Samsung Galaxy S) to be able to use the camera again.
In the DDM, after the crash i can see the following line: keyDispatchingTimedOut
Here is the relevant code:
CameraActivity Class:
public class CameraActivity extends Activity {
private static final String TAG = "CameraDemo";
Preview preview;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
preview = new Preview(this);
((FrameLayout) findViewById(R.id.preview)).addView(preview);
((FrameLayout) findViewById(R.id.preview)).setOnTouchListener(preview);
Log.d(TAG, "Camera Activity Created.");
}
}
Preview Class:
class Preview extends SurfaceView implements SurfaceHolder.Callback, OnTouchListener {
private static final String TAG = "Preview";
SurfaceHolder mHolder;
public Camera camera;
Context ctx;
boolean previewing = false;
Preview(Context context) {
super(context);
ctx = context;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
// Called once the holder is ready
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
camera = Camera.open();
}
// Called when the holder is destroyed
public void surfaceDestroyed(SurfaceHolder holder) {
if (camera != null) {
camera.setPreviewCallback(null);
camera.stopPreview();
camera.release();
camera = null;
}
previewing = false;
}
// Called when holder has changed
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if(previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
camera.setDisplayOrientation(90);
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(new PreviewCallback() {
// Called for each frame previewed
public void onPreviewFrame(byte[] data, Camera camera) {
Log.d(TAG, "onPreviewFrame called at: " + System.currentTimeMillis());
Preview.this.invalidate();
}
});
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public boolean onTouch(View v, MotionEvent event) {
camera.takePicture(shutterCallback, rawCallback, jpegCallback);
return false;
}
// Called when shutter is opened
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
Log.d(TAG, "onShutter'd");
}
};
// Handles data for raw picture
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "onPictureTaken - raw");
}
};
// Handles data for jpeg picture
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
// Write to SD Card
outStream = new FileOutputStream(String.format("/sdcard/TVguide/Detection/detected.jpg", System.currentTimeMillis())); // <9>
outStream.write(data);
outStream.close();
Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) { // <10>
//Toast.makeText(ctx, "Exception #2", Toast.LENGTH_LONG).show();
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {}
Log.d(TAG, "onPictureTaken - jpeg");
Toast.makeText(ctx, "SAVED", Toast.LENGTH_SHORT).show();
camera.startPreview();
}
};
}
Please help, i am trying a few days to understand where the problem is with no success
Eyal
I just run into this issue when testing my application on a Samsung Galaxy SII. You just have to remove the preview callback before taking the picture:
mCamera.setPreviewCallback(null);
mCamera.takePicture(null, null, mPictureCallback);
I don't know what causes that bug, it would really help if you posted the loggcat output from the time from when this error happened.
But, I can make some gusesses. It looks like camera is locked (built-in camera does not work). If your app force closed, the camera lock might be caused by erroneus error handling in Samsung camera HAL. Especially in older phones, like Galaxy S, they did not do the best job at handling wrong, or not standard API calls.
Here are some suggestions of what may have caused this behaviour:
You should add a guard for picture taking. Right now, if you touch the screen and take picture, you can touch the screen again, before the picture finishes taking. So, camera.takePicture() will be called twice. The second one will fail. This is my best guess.
Add some boolean isTakingPicture = false variable and then:
public boolean onTouch(View v, MotionEvent event) {
if (!isTakingPicture) {
camera.takePicture(shutterCallback, rawCallback, jpegCallback);
isTakingPicture = true;
}
return false;
}
...
public void onPictureTaken(byte[] data, Camera camera) {
isTakingPicture = false;
...
What do you use previewCallback for? I doesn't do anything useful here. Preview callbacks sometimes can sometimes cause some pain, although your code looks fine to me. You can alwys try to remove it and check if that helps.
I experienced a similar issue reported here. On LG p705 and Samsung Galaxy Trend, after taking a photo, the preview is frozen and camera was no longer usable until the phone was restarted. On Galaxy S3 however, the preview continues to display properly even after multiple photo snaps.
While debugging, I noticed that the relevant listener class was receiving more than one call when the camera button was pressed to take picture. I am unsure why it is being invoked twice, even though the button was only click once. In any case, thanks to Tomasz's suggestion to use of a boolean variable, the second call skips taking photo while the first attempt is in progress. And thanks Eyal for the question too. :)

Camera application using SurfaceView crashing

The application crashes(Before anything starts there's a dialog that has to be forced closed and then the app exits) at setPreviewDisplay(holder) in SurfaceCreated and I can't figure out why.
Please advise. Below is my code.
public void onCreate(Bundle savedInstanceState) {
cameraPreview = new CameraPreview();//CameraPreview has a methos to open the Camera
cameraObject = CameraPreview.getCameraInstance();
mHolder = previewSurface.getHolder();//previewSurface is the SurfaceView declared in XML and then I'm doinf findViewById
mHolder.addCallback(this);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
cameraObject.setPreviewDisplay(holder); //CRASHES HERE
//cameraObject.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 {
cameraObject.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// make any resize, rotate or reformatting changes here
// start preview with new settings
try {
cameraObject.setPreviewDisplay(mHolder);
cameraObject.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
In surfaceCreated, just before setPreviewDisplay, it needs Camera.open and then calling the said method on the camera object.
There cannot be any other statement in between these two otherwise it crashes.

Categories

Resources