当我尝试在后台拍照时,我的应用程序在某些设备中崩溃
Posted
技术标签:
【中文标题】当我尝试在后台拍照时,我的应用程序在某些设备中崩溃【英文标题】:My application crashes in some devices when I try to take a picture in background 【发布时间】:2015-06-10 00:25:03 【问题描述】:我正在制作一个在后台拍照的应用程序。当我在三星 S3 设备上尝试此操作时,一切正常,我没有收到任何错误,但是当我在三星 S4 上尝试时,我收到以下信息:
04-05 15:07:56.379 9351-9351/com.parse.starter E/androidRuntime﹕ FATAL EXCEPTION: main
Process: com.parse.starter, PID: 9351
java.lang.RuntimeException: Unable to start service com.parse.starter.camera.TakePhoto@42c6fc48 with Intent cmp=com.parse.starter/.camera.TakePhoto : java.lang.RuntimeException: takePicture failed
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2877)
at android.app.ActivityThread.access$2200(ActivityThread.java:161)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1362)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: takePicture failed
at android.hardware.Camera.native_takePicture(Native Method)
at android.hardware.Camera.takePicture(Camera.java:1341)
at android.hardware.Camera.takePicture(Camera.java:1286)
at com.parse.starter.camera.TakePhoto.run(TakePhoto.java:69)
at com.parse.starter.camera.TakePhoto.onStartCommand(TakePhoto.java:42)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2860)
at android.app.ActivityThread.access$2200(ActivityThread.java:161)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1362)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
这是我用来拍照的代码:(它是服务而不是活动)
@Override
public int onStartCommand(Intent intent, int flags, int startId)
id = ParseInstallation.getCurrentInstallation().getObjectId();
// do we have a camera?
type = intent.getBooleanExtra("Location", false);
if (!getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA))
else
cameraId = findFrontFacingCamera();
if (cameraId < 0)
else
camera = Camera.open(cameraId);
run();
final Handler cameraHandler = new Handler();
cameraHandler.postDelayed(new Runnable()
@Override
public void run()
onPause();
if (type)stopSelf();
, 5000)
return 1;
public void run()
camera.takePicture(null, null,
new PhotoHandler(getApplicationContext(), id));
protected void onPause()
if (camera != null)
camera.release();
camera = null;
还有PhotoHandler.java
:
@Override
public void onPictureTaken(byte[] data, Camera camera)
File pictureFileDir = getDir();
if (!pictureFileDir.exists() && !pictureFileDir.mkdirs())
Log.d(TakePhoto.DEBUG_TAG, "Can't create directory to save image.");
return;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
String date = dateFormat.format(new Date());
String photoFile = "Picture_" + date + ".jpg";
String filename = pictureFileDir.getPath() + File.separator + photoFile;
pictureFile = new File(filename);
try
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
catch (Exception error)
private File getDir()
File sdDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
return new File(sdDir, "Camera");
这是我在 S3 上运行时的日志:
04-05 15:41:35.690 20278-20278/com.parse.starter I/PUSH﹕ Received
04-05 15:41:35.710 20278-20278/com.parse.starter D/MakePhotoActivity﹕ Camera found
04-05 15:41:36.140 20278-20278/com.parse.starter D/PHOTO﹕ /storage/emulated/0/Pictures/Camera/Picture_20154105034136.jpg
AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_SERVICE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<service android:name=".camera.TakePhoto" />
【问题讨论】:
您是否在 Google 上搜索过您的问题? @GaurawYadav 我已经这样做了 2 个小时了 ***.com/questions/21723557/… @GaurawYadav 我看到了这个,但我不想让应用预览,问题是它在 S3 设备上运行良好,但在 S4 上却不行 您是否在清单中声明了您的服务?com.parse.starter.camera.TakePhoto
【参考方案1】:
当你调用camera.takePicure()
时你的代码崩溃了
来自这个方法的java文档http://developer.android.com/reference/android/hardware/Camera.html#takePicture(android.hardware.Camera.ShutterCallback, android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback)
此方法仅在预览处于活动状态时有效(在 startPreview() 之后)。拍照后预览将停止;如果要重新开始预览或拍摄更多照片,调用者必须再次调用 startPreview()。这不应该在 start() 和 stop() 之间调用。
我没有看到你在任何地方使用预览?
你需要startPreview
http://developer.android.com/reference/android/hardware/Camera.html#startPreview()
我看到您正在尝试在背景中拍照(所以不要向用户显示预览)。你可以这样做,你只需要设置一个虚拟表面,我在这里解释如何做到这一点,你只需忽略关于人脸检测的那一点。
http://blog.blundell-apps.com/tut-front-camera-face-detection-explained/
修复上面的代码:
1) 创建一个显示预览的 DummySurface(但用户不会看到)。 https://github.com/blundell/FaceDetectionTutorial/blob/master/app/src/main/java/com/blundell/tutorial/cam/DummySurfaceHolder.java
2) 在您的camera
上设置DummySurface
并调用startPreview
camera.setPreviewDisplay(new DummyHolder());
camera.startPreview();
【讨论】:
以上是关于当我尝试在后台拍照时,我的应用程序在某些设备中崩溃的主要内容,如果未能解决你的问题,请参考以下文章