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);
}
}
Related
I am working on an Android application which programatically capture image using both front and back camera and save to a folder in the internal memory.
Once the image is saved the application will send the contents of the folder through email. How to wait the application till images captured completely, otherwise a blank email is send?
class MainActivity{
//other codes
public void buttonClick(View v) {
CameraService.startCamera(0, true);
sendEmail();
}
public void sendEmail()
{
//get contents from the folder and send the contents using java mail api
}
}
This is the class which capture image using both front and back camera.
class CamearService
{
public static void startCamera(int cameraID,final boolean isFirstTime) {
mCamera = Camera.open(cameraID);
try {
mCamera.setPreviewTexture(new SurfaceTexture(10));
} catch (IOException e1) {
}
Parameters params = mCamera.getParameters();
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
params.setPictureFormat(ImageFormat.JPEG);
params.setJpegQuality(100);
mCamera.setParameters(params);
mCamera.startPreview();
mCamera.takePicture(null, null, null, new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.i("hello", "picture-taken");
if (data != null) {
mCamera.stopPreview();
mCamera.release();
try {
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
data.length, opts);
storeImage(bitmap); //function to store image to local folder
if(isFirstTime)
{
//Capture using front camera
CameraService.startCamera(1, false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
}
when i click on the button startCamera() function is executed and before capturing the second image sendEmail() function is executed. As a result only one image is send through email.
What you are looking for is basic programming concept called Callbacks (which you are using with the Camera.takePicture() method call).
Please read my answer here as it is apply as well to your case:
Handle data returned by an Async task (Firebase)
I was working on an android app that is using the camera (CWAC) and it worked ok before updating to android 5.0.2, after the update if I take a picture the camera.takePicture is called in CameraView:
postDelayed(new Runnable() {
#Override
public void run() {
try {
camera.takePicture(xact, new PictureTransactionCallback(xact),
new PictureTransactionCallback(xact));
}
catch (Exception e) {
android.util.Log.e(getClass().getSimpleName(),
"Exception taking a picture", e);
// TODO get this out to library clients
}
}
}, xact.host.getDeviceProfile().getPictureDelay());
This is the PictureTransactionCallback:
private class PictureTransactionCallback implements
Camera.PictureCallback {
PictureTransaction xact=null;
PictureTransactionCallback(PictureTransaction xact) {
this.xact=xact;
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
camera.setParameters(previewParams);
if (data != null) {
new ImageCleanupTask(getContext(), data, cameraId, xact).start();
}
if (!xact.useSingleShotMode()) {
startPreview();
}
}
}
The problem is that if I run the app on android 5.0.2 onPictureTaken from the PictureTransactionCallback is never triggered (I ran the app with debug) on the same phone but with android 4.4.2 onPictureTaken is triggered and simpleCameraHost.saveImage is called. I can't find the cause of the problem.
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
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.
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. :)