问题,我能够第一次捕获,但当我试图第二次捕获时,发生以下异常.
4-19 11:28:32.509: E/AndroIDRuntime(4409): FATAL EXCEPTION: main04-19 11:28:32.509: E/AndroIDRuntime(4409): java.lang.RuntimeException: takePicture Failed04-19 11:28:32.509: E/AndroIDRuntime(4409): at androID.harDWare.Camera.native_takePicture(Native Method)04-19 11:28:32.509: E/AndroIDRuntime(4409): at androID.harDWare.Camera.takePicture(Camera.java:878)04-19 11:28:32.509: E/AndroIDRuntime(4409): at androID.harDWare.Camera.takePicture(Camera.java:842)04-19 11:28:32.509: E/AndroIDRuntime(4409): at com.example.camerasample.MainActivity.onClick(MainActivity.java:60)04-19 11:28:32.509: E/AndroIDRuntime(4409): at androID.vIEw.VIEw.performClick(VIEw.java:2485)04-19 11:28:32.509: E/AndroIDRuntime(4409): at androID.vIEw.VIEw$PerformClick.run(VIEw.java:9080)04-19 11:28:32.509: E/AndroIDRuntime(4409): at androID.os.Handler.handleCallback(Handler.java:587)04-19 11:28:32.509: E/AndroIDRuntime(4409): at androID.os.Handler.dispatchMessage(Handler.java:92)04-19 11:28:32.509: E/AndroIDRuntime(4409): at androID.os.Looper.loop(Looper.java:130)04-19 11:28:32.509: E/AndroIDRuntime(4409): at androID.app.ActivityThread.main(ActivityThread.java:3687)04-19 11:28:32.509: E/AndroIDRuntime(4409): at java.lang.reflect.Method.invokeNative(Native Method)04-19 11:28:32.509: E/AndroIDRuntime(4409): at java.lang.reflect.Method.invoke(Method.java:507)04-19 11:28:32.509: E/AndroIDRuntime(4409): at com.androID.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)04-19 11:28:32.509: E/AndroIDRuntime(4409): at com.androID.internal.os.ZygoteInit.main(ZygoteInit.java:625)04-19 11:28:32.509: E/AndroIDRuntime(4409): at dalvik.system.NativeStart.main(Native Method)
但是在没有自动对焦功能的相机中捕获时工作正常.
下面我附上了我的代码
MainActivity.java
package com.example.camerasample;import java.io.fileNotFoundException;import java.io.fileOutputStream;import java.io.IOException;import com.example.camerasample.R;import androID.app.Activity;import androID.content.Context;import androID.harDWare.Camera;import androID.harDWare.Camera.autoFocusCallback;import androID.harDWare.Camera.PictureCallback;import androID.harDWare.Camera.ShutterCallback;import androID.os.Bundle;import androID.util.Log;import androID.vIEw.SurfaceVIEw;import androID.vIEw.VIEw;import androID.vIEw.VIEw.OnClickListener;import androID.vIEw.VIEw.OnLongClickListener;import androID.vIEw.VIEwGroup.LayoutParams;import androID.vIEw.Window;import androID.vIEw.WindowManager;import androID.Widget.button;import androID.Widget.FrameLayout;public class MainActivity extends Activity { private static final String TAG = "CamTestActivity"; PrevIEw prevIEw; button buttonClick; Camera camera; String filename; Activity act; Context ctx; @OverrIDe public voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ctx = this; act = this; requestwindowFeature(Window.FEATURE_NO_Title); getwindow().addFlags(WindowManager.LayoutParams.FLAG_FulLSCREEN); setContentVIEw(R.layout.activity_main); prevIEw = new PrevIEw(this,(SurfaceVIEw)findVIEwByID(R.ID.surfaceVIEw)); prevIEw.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); ((FrameLayout) findVIEwByID(R.ID.prevIEw)).addVIEw(prevIEw); prevIEw.setKeepScreenOn(true); buttonClick = (button) findVIEwByID(R.ID.buttonClick); buttonClick.setonClickListener(new OnClickListener() { public voID onClick(VIEw v) { camera.takePicture(shutterCallback,rawCallback,jpegCallback); } }); buttonClick.setonLongClickListener(new OnLongClickListener(){ @OverrIDe public boolean onLongClick(VIEw arg0) { camera.autoFocus(new autoFocusCallback(){ @OverrIDe public voID onautoFocus(boolean arg0,Camera arg1) { } }); return true; } }); } @OverrIDe protected voID onResume() { super.onResume(); camera = Camera.open(); camera.startPrevIEw(); prevIEw.setCamera(camera); } @OverrIDe protected voID onPause() { if(camera != null) { camera.stopPrevIEw(); prevIEw.setCamera(null); camera.release(); camera = null; } super.onPause(); } private voID resetCam() { camera.startPrevIEw(); prevIEw.setCamera(camera); } ShutterCallback shutterCallback = new ShutterCallback() { public voID onShutter() { // Log.d(TAG,"onShutter'd"); } }; PictureCallback rawCallback = new PictureCallback() { public voID onPictureTaken(byte[] data,Camera camera) { // Log.d(TAG,"onPictureTaken - raw"); } }; PictureCallback jpegCallback = new PictureCallback() { public voID onPictureTaken(byte[] data,Camera camera) { fileOutputStream outStream = null; try { // Write to SD Card filename = String.format("/sdcard/camtest/%d.jpg",System.currentTimeMillis()); outStream = new fileOutputStream(filename); outStream.write(data); outStream.close(); Log.d(TAG,"onPictureTaken - wrote bytes: " + data.length); resetCam(); } catch (fileNotFoundException e) { e.printstacktrace(); } catch (IOException e) { e.printstacktrace(); } finally { } Log.d(TAG,"onPictureTaken - jpeg"); } };}
PrevIEw.java
package com.example.camerasample;import java.io.IOException;import java.util.List;import androID.content.Context;import androID.harDWare.Camera;import androID.harDWare.Camera.Size;import androID.util.Log;import androID.vIEw.SurfaceHolder;import androID.vIEw.SurfaceVIEw;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;class PrevIEw extends VIEwGroup implements SurfaceHolder.Callback { private final String TAG = "PrevIEw"; SurfaceVIEw mSurfaceVIEw; SurfaceHolder mHolder; Size mPrevIEwSize; List<Size> mSupportedPrevIEwSizes; Camera mCamera; @SuppressWarnings("deprecation") PrevIEw(Context context,SurfaceVIEw sv) { super(context); mSurfaceVIEw = sv; mHolder = mSurfaceVIEw.getHolder(); mHolder.addCallback(this); mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public voID setCamera(Camera camera) { mCamera = camera; if (mCamera != null) { mSupportedPrevIEwSizes = mCamera.getParameters().getSupportedPrevIEwSizes(); requestLayout(); // get Camera parameters Camera.Parameters params = mCamera.getParameters(); List<String> focusModes = params.getSupportedFocusModes(); if (focusModes.contains(Camera.Parameters.FOCUS_MODE_auto)) { // set the focus mode params.setFocusMode(Camera.Parameters.FOCUS_MODE_auto); // set Camera parameters mCamera.setParameters(params); } } } @OverrIDe protected voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) { // We purposely disregard child measurements because act as a // wrapper to a SurfaceVIEw that centers the camera prevIEw instead // of stretching it. final int wIDth = resolveSize(getSuggestedMinimumWIDth(),wIDthMeasureSpec); final int height = resolveSize(getSuggestedMinimumHeight(),heightmeasureSpec); setMeasuredDimension(wIDth,height); if (mSupportedPrevIEwSizes != null) { mPrevIEwSize = getoptimalPrevIEwSize(mSupportedPrevIEwSizes,wIDth,height); } } @OverrIDe protected voID onLayout(boolean changed,int l,int t,int r,int b) { if (changed && getChildCount() > 0) { final VIEw child = getChildAt(0); final int wIDth = r - l; final int height = b - t; int prevIEwWIDth = wIDth; int prevIEwHeight = height; if (mPrevIEwSize != null) { prevIEwWIDth = mPrevIEwSize.wIDth; prevIEwHeight = mPrevIEwSize.height; } // Center the child SurfaceVIEw within the parent. if (wIDth * prevIEwHeight > height * prevIEwWIDth) { final int scaledChilDWIDth = prevIEwWIDth * height / prevIEwHeight; child.layout((wIDth - scaledChilDWIDth) / 2,(wIDth + scaledChilDWIDth) / 2,height); } else { final int scaledChildHeight = prevIEwHeight * wIDth / prevIEwWIDth; child.layout(0,(height - scaledChildHeight) / 2,(height + scaledChildHeight) / 2); } } } public voID surfaceCreated(SurfaceHolder holder) { // The Surface has been created,acquire the camera and tell it where // to draw. try { if (mCamera != null) { mCamera.setPrevIEwdisplay(holder); } } catch (IOException exception) { Log.e(TAG,"IOException caused by setPrevIEwdisplay()",exception); } } public voID surfaceDestroyed(SurfaceHolder holder) { // Surface will be destroyed when we return,so stop the prevIEw. if (mCamera != null) { mCamera.stopPrevIEw(); } } private Size getoptimalPrevIEwSize(List<Size> sizes,int w,int h) { final double ASPECT_TolERANCE = 0.1; double targetRatio = (double) w / h; if (sizes == null) return null; Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; // Try to find an size match aspect ratio and size for (Size size : sizes) { double ratio = (double) size.wIDth / size.height; if (Math.abs(ratio - targetRatio) > ASPECT_TolERANCE) continue; if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } // Cannot find the one match the aspect ratio,ignore the requirement if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; } public voID surfaceChanged(SurfaceHolder holder,int format,int h) { if(mCamera != null) { Camera.Parameters parameters = mCamera.getParameters(); parameters.setPrevIEwSize(mPrevIEwSize.wIDth,mPrevIEwSize.height); requestLayout(); mCamera.setParameters(parameters); mCamera.startPrevIEw(); } }}
表现:
<?xml version="1.0" enCoding="utf-8"?><manifest xmlns:androID="http://schemas.androID.com/apk/res/androID" package="com.example.camerasample" androID:versionCode="1" androID:versionname="1.0" > <uses-sdk androID:minSdkVersion="8" /> <uses-feature androID:name="androID.harDWare.camera" /> <uses-permission androID:name="androID.permission.CAMERA" /> <uses-permission androID:name="androID.harDWare.camera.autofocus" /> <uses-permission androID:name="androID.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission androID:name="androID.permission.INTERNET" /> <uses-permission androID:name="androID.permission.ACCESS_NETWORK_STATE" /> <application androID:icon="@drawable/ic_launcher" androID:label="@string/app_name" > <activity androID:label="@string/app_name" androID:name=".MainActivity" androID:screenorIEntation="landscape" > <intent-filter > <action androID:name="androID.intent.action.MAIN" /> <category androID:name="androID.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest>
我无法在任何地方找到确切的解决方案,请帮忙.
解决方法 我提出了两个对我有用的解决方案.1)正确停止并恢复相机.我是通过调用这些方法来实现的
onPause和onResume,也在相机预览的中间,我在我的应用程序中扫描QR码:
public voID stopCamera(){ mCamera.cancelautoFocus(); mCamera.setPrevIEwCallback(null); mCamera.stopPrevIEw(); mPrevIEwing = false; }public voID rethrottleCamera(){ updateVIEws(); //Updates my Layouts mPrevIEwing = true; mCamera.startPrevIEw(); mCamera.setPrevIEwCallback(prevIEwCb); mCamera.autoFocus(autoFocusCB); }
2)非常棘手,但像魔术一样工作!确保在创建预览曲面后调用自动对焦.要执行此 *** 作,请以200毫秒的延迟运行自动对焦,以便为要创建的曲面购买时间.通过在“CameraPrevIEw”对象声明上按ctrl clic来设置此项,例如:
CameraPrevIEw my_camera;
查找“public voID surfaceChanged”方法并进行此更改:
//Add a delay to autoFOCUS after mCamera.startprevIEw();!!: mCamera.startPrevIEw(); final Handler handler = new Handler(); handler.postDelayed(new Runnable() { @OverrIDe public voID run() { mCamera.autoFocus(autoFocusCallback); } },200); //<-200 millisecond delay //If you call autofocus right after startPrevIEw,chances are,//that the prevIEwSurface will have not been created yet,//and autofocus will fail: mCamera.startPrevIEw(); //Bad IDea! mCamera.autoFocus(autoFocusCallback); //Bad IDea!
还有很多其他修复,但这两个可能会节省您的一天.
总结以上是内存溢出为你收集整理的android – takePicture第二次自动对焦后失败全部内容,希望文章能够帮你解决android – takePicture第二次自动对焦后失败所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)