android – takePicture第二次自动对焦后失败

android – takePicture第二次自动对焦后失败,第1张

概述我正在开发一个使用自动对焦的 Android相机应用程序. 问题,我能够第一次捕获,但当我试图第二次捕获时,发生以下异常. 4-19 11:28:32.509: E/AndroidRuntime(4409): FATAL EXCEPTION: main04-19 11:28:32.509: E/AndroidRuntime(4409): java.lang.RuntimeException: t 我正在开发一个使用自动对焦的 Android相机应用程序.

问题,我能够第一次捕获,但当我试图第二次捕获时,发生以下异常.

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第二次自动对焦后失败所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1128854.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-30
下一篇 2022-05-30

发表评论

登录后才能评论

评论列表(0条)

保存