Android: java.lang.RuntimeException: takePicture échoué

Je suis suis en train de capturer une image en ontouchevent de surfaceview. Cependant, à chaque fois une touche de l'écran, l'application se bloque avec l'exception suivante:

01-05 21:03:18.500: ERROR/AndroidRuntime(10367): FATAL EXCEPTION: main
java.lang.RuntimeException: takePicture failed
at android.hardware.Camera.native_takePicture(Native Method)
at android.hardware.Camera.takePicture(Camera.java:1126)
at android.hardware.Camera.takePicture(Camera.java:1071)
at com.test.MotionDetector.CameraSurfaceView.onTouchEvent(CameraSurfaceView.java:107)
at android.view.View.dispatchTouchEvent(View.java:7350)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2151)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1480)
at android.app.Activity.dispatchTouchEvent(Activity.java:2469)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2099)
at android.view.View.dispatchPointerEvent(View.java:7535)
at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3492)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3424)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4534)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4512)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4616)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:125)
at android.os.Looper.loop(Looper.java:124)
at android.app.ActivityThread.main(ActivityThread.java:4921)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
at dalvik.system.NativeStart.main(Native Method)

Mon code:

package com.nadim.MotionDetector;
import android.content.Context;
import android.hardware.Camera;
import android.os.Environment;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private Context context;
public CameraSurfaceView(Context context, Camera camera) {
super(context);
this.context = 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("MotionDetector", "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("MotionDetector", "Error starting camera preview: " + e.getMessage());
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Toast.makeText(context, "Picture taken", Toast.LENGTH_SHORT).show();
//System.gc(); tried this because it was suggested in a stackoverflow question but it didn't help.
mCamera.takePicture(null, mPicture, mPicture);
return true; //processed
}
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d("MotionDetector", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("MotionDetector", "Error accessing file: " + e.getMessage());
}
}
};
private static File getOutputMediaFile() {
File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), "motiondetect");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
//Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir, timeStamp + ".jpg");
return mediaFile;
}
}

Les autorisations et les fonctionnalités utilisées:

<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera.flash" />

Je ne sais pas pourquoi l'incident se produit. Beaucoup d'autres sujet conseille d'appeler la Caméra.startPreview premier. Je suis en train de faire ça, mais ça ne résout pas le problème.

LogCat avant de prendre une photo:

01-05 21:45:57.667: WARN/ActivityManager(754): No content provider found for permission revoke: file:///data/local/tmp/com.test.MotionDetector
01-05 21:45:57.667: WARN/ActivityManager(754): No content provider found for permission revoke: file:///data/local/tmp/com.test.MotionDetector
01-05 21:45:57.687: INFO/ActivityManager(754): Force stopping com.test.MotionDetector appid=10103 user=-1: uninstall pkg
01-05 21:45:57.687: INFO/ActivityManager(754): Killing 4264:com.test.MotionDetector/u0a103 (adj 7): stop com.test.MotionDetector
01-05 21:45:57.687: INFO/ActivityManager(754): Force finishing activity ActivityRecord{437a6678 u0 com.test.MotionDetector/.MotionDetectActivity t144}
01-05 21:45:57.697: WARN/InputDispatcher(754): channel '42adff40 com.test.MotionDetector/com.test.MotionDetector.MotionDetectActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x9
01-05 21:45:57.697: ERROR/InputDispatcher(754): channel '42adff40 com.test.MotionDetector/com.test.MotionDetector.MotionDetectActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
01-05 21:45:57.697: WARN/InputDispatcher(754): Attempted to unregister already unregistered input channel '42adff40 com.test.MotionDetector/com.test.MotionDetector.MotionDetectActivity (server)'
01-05 21:45:57.697: INFO/WindowState(754): WIN DEATH: Window{42adff40 u0 com.test.MotionDetector/com.test.MotionDetector.MotionDetectActivity}
01-05 21:45:57.757: INFO/PackageManager(754): Running dexopt on: com.test.MotionDetector
01-05 21:45:57.757: INFO/PackageManager(754): Package com.test.MotionDetector codePath changed from /data/app/com.test.MotionDetector-1.apk to /data/app/com.test.MotionDetector-2.apk; Retaining data and using new
01-05 21:45:57.807: INFO/ActivityManager(754): Force stopping com.test.MotionDetector appid=10103 user=-1: update pkg
01-05 21:45:57.807: WARN/PackageManager(754): Code path for pkg : com.test.MotionDetector changing from /data/app/com.test.MotionDetector-1.apk to /data/app/com.test.MotionDetector-2.apk
01-05 21:45:57.807: WARN/PackageManager(754): Resource path for pkg : com.test.MotionDetector changing from /data/app/com.test.MotionDetector-1.apk to /data/app/com.test.MotionDetector-2.apk
01-05 21:45:57.937: INFO/ActivityManager(754): Force stopping com.test.MotionDetector appid=10103 user=0: pkg removed
01-05 21:45:57.987: DEBUG/BackupManagerService(754): Received broadcast Intent { act=android.intent.action.PACKAGE_REMOVED dat=package:com.test.MotionDetector flg=0x4000010 (has extras) }
01-05 21:45:58.047: DEBUG/BackupManagerService(754): Received broadcast Intent { act=android.intent.action.PACKAGE_ADDED dat=package:com.test.MotionDetector flg=0x4000010 (has extras) }
01-05 21:45:58.567: INFO/Icing.InternalIcingCorporaProvider(12750): Updating corpora: A: com.test.MotionDetector, C: MAYBE
01-05 21:45:58.647: DEBUG/PackageAddedReceiver(1086): package added com.test.MotionDetector
01-05 21:45:58.737: INFO/ActivityManager(754): START u0 {flg=0x10000000 cmp=com.test.MotionDetector/.MotionDetectActivity} from pid 4578
01-05 21:45:58.777: INFO/ActivityManager(754): Start proc com.test.MotionDetector for activity com.test.MotionDetector/.MotionDetectActivity: pid=4630 uid=10103 gids={50103, 1028, 1015}
01-05 21:45:59.627: INFO/ActivityManager(754): Displayed com.test.MotionDetector/.MotionDetectActivity: +861ms (total +972ms)
01-05 21:45:59.657: INFO/WindowManager(754): Screen frozen for +869ms due to Window{43cb77a8 u0 com.test.MotionDetector/com.test.MotionDetector.MotionDetectActivity}
  • Manquant permissions dans le fichier de manifeste?
  • ce qui est à montrer dans logcat avant le crash?
  • Voir des changements dans la question
InformationsquelleAutor MeesterPatat | 2014-01-05