java.lang.RuntimeException的:takePicture失败 [英] java.lang.RuntimeException: takePicture failed

查看:1830
本文介绍了java.lang.RuntimeException的:takePicture失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我这样做连续点击捕捉按钮(没有任何中断),获得运行时异常 我怎样才能解决这个问题呢?

如果它无法让我怎么可能处理这个异常?

  btnCapture =(的ImageButton)findViewById(R.id.btnCapture);
                最后的MediaPlayer MP = MediaPlayer.create(CameraLauncherActivity.this,R.raw.button);
                btnCapture.setOnClickListener(新View.OnClickListener(){
                    @覆盖
                    公共无效的onClick(视图v){

                            //行那里获得的RuntimeException
                        camera.takePicture(NULL,NULL,mPicture);

                    }
                });
 

登录:

  02-12 14:48:41.580:E / AndroidRuntime(6997):致命异常:主要
02-12 14:48:41.580:E / AndroidRuntime(6997):java.lang.RuntimeException的:takePicture失败
02-12 14:48:41.580:E / AndroidRuntime(6997):在android.hardware.Camera.native_takePicture(本机方法)
02-12 14:48:41.580:E / AndroidRuntime(6997):在android.hardware.Camera.takePicture(Camera.java:1126)
02-12 14:48:41.580:E / AndroidRuntime(6997):在android.hardware.Camera.takePicture(Camera.java:1071)
02-12 14:48:41.580:E / AndroidRuntime(6997):在app.cam.shane.CameraLauncherActivity $ 3.onClick(CameraLauncherActivity.java:116)
02-12 14:48:41.580:E / AndroidRuntime(6997):在android.view.View.performClick(View.java:4223)
02-12 14:48:41.580:E / AndroidRuntime(6997):在android.view.View $ PerformClick.run(View.java:17275)
02-12 14:48:41.580:E / AndroidRuntime(6997):在android.os.Handler.handleCallback(Handler.java:615)
02-12 14:48:41.580:E / AndroidRuntime(6997):在android.os.Handler.dispatchMessage(Handler.java:92)
02-12 14:48:41.580:E / AndroidRuntime(6997):在android.os.Looper.loop(Looper.java:137)
02-12 14:48:41.580:E / AndroidRuntime(6997):在android.app.ActivityThread.main(ActivityThread.java:4921)
02-12 14:48:41.580:E / AndroidRuntime(6997):在java.lang.reflect.Method.invokeNative(本机方法)
02-12 14:48:41.580:E / AndroidRuntime(6997):在java.lang.reflect.Method.invoke(Method.java:511)
02-12 14:48:41.580:E / AndroidRuntime(6997):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1036)
02-12 14:48:41.580:E / AndroidRuntime(6997):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:803)
02-12 14:48:41.580:E / AndroidRuntime(6997):在dalvik.system.NativeStart.main(本机方法)
 

注意: - 就像布丁相机,它们允许用户做就捕获按钮连续的自来水,但他们将永远不会显示异常,如果你做50点击它会捕捉10个或更多的图像,经过特定的时间每​​幅图像,但没有显示异常,像我得到我的code,以同样的方式我怎么处理这个异常?

完成code:

  @覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);

    的setContentView(R.layout.activity_camera);

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

            preVIEW =(SurfaceView)findViewById(R.id.surface);
            previewHolder = preview.getHolder();
            previewHolder.addCallback(surfaceCallback);
            previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

            btnCapture =(的ImageButton)findViewById(R.id.btnCapture);
            最后的MediaPlayer MP = MediaPlayer.create(CameraLauncherActivity.this,R.raw.button);
            btnCapture.setOnClickListener(新View.OnClickListener(){
                @覆盖
                公共无效的onClick(视图v){
                    mp.start();
                    camera.takePicture(NULL,NULL,mPicture);
                }
            });


    @覆盖
    公共无效onResume(){
        super.onResume();
        相机= Camera.open();
    }

    @覆盖
    公共无效的onPause(){
        super.onPause();
        如果(在preVIEW){
        camera.stop preVIEW();
        }
        camera.release();
        摄像头= NULL;
        在preVIEW = FALSE;
    }


    私人Camera.Size getBest previewSize(INT宽度,高度INT,
            Camera.Parameters参数){
            Camera.Size结果= NULL;

            对于(Camera.Size大小:parameters.getSupported previewSizes()){
                如果(size.width< =宽度放大器;&安培; size.height< =身高){
                    如果(结果== NULL){
                        结果=大小;
                    }
                    其他 {
                        INT resultArea = result.width * result.height;
                        INT newArea = size.width * size.height;

                        如果(newArea> resultArea){
                            结果=大小;
                        }
                    }
                }
            }

            返回(结果);
        }

    私人Camera.Size getSmallestPictureSize(Camera.Parameters参数){
        Camera.Size结果= NULL;

        对于(Camera.Size尺寸:parameters.getSupportedPictureSizes()){
            如果(结果== NULL){
                结果=大小;
            }
            其他 {
                INT resultArea = result.width * result.height;
                INT newArea = size.width * size.height;

                如果(newArea< resultArea){
                    结果=大小;
                }
            }
        }

        返回(结果);
    }


    SurfaceHolder.Callback surfaceCallback =新SurfaceHolder.Callback(){

    公共无效surfaceCreated(SurfaceHolder持有者){
        尝试 {
            camera.set previewDisplay(previewHolder);
            }赶上(的Throwable T){
                Log.e(previewDemo-surfaceCallback
                        异常的一套previewDisplay(),T);
                Toast.makeText(CameraLauncherActivity.this,t.getMessage(),Toast.LENGTH_LONG).show();
                }
            }

    公共无效surfaceChanged(SurfaceHolder持有人,INT格式,诠释的宽度,高度INT){
        PARAMS = camera.getParameters();
        params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
        Camera.Size大小= getBest previewSize(宽度,高度,PARAMS);
        Camera.Size pictureSize = getSmallestPictureSize(PARAMS);
        如果(大小= NULL和放大器;!&安培;!pictureSize = NULL){
            params.set previewSize(size.width,size.height);
            params.setPictureSize(pictureSize.width,
                    pictureSize.height);
            camera.setParameters(PARAMS);
            camera.start preVIEW();
            在preVIEW = TRUE;

            }
        }

    公共无效surfaceDestroyed(SurfaceHolder持有者){

        }
    };

    PictureCallback mPicture =新PictureCallback(){
        @覆盖
        公共无效onPictureTaken(byte []的数据,摄像头摄像头){
            PictureFile的= getOutputMediaFile();
            camera.start preVIEW();
            如果(PictureFile的== NULL){
                返回;
            }
            尝试 {
                FileOutputStream中FOS =新的FileOutputStream(PictureFile的);
                fos.write(数据);
                fos.close();
            }赶上(FileNotFoundException异常E){

            }赶上(IOException异常E){
            }
        }
    };

    静态文件getOutputMediaFile(){

        / * YYYY-MM-dd'T'HH:毫米:ss.SSSZ * /
        的timeStamp =新的SimpleDateFormat(YYYYMMDD_HHMMSS)
        .format(新日期());

        // 文件名
        媒体文件=新的文件(LoginActivity.mediaStorageDir.getPath()+文件分割符
                +IMG_+的timeStamp +.JPG);

        返回媒体文件;

    }


}
 

解决方案

首先,赶上onPictureTaken你例外,留下空的catch部分是不是一个好的做法。然后,我想补充一个标志,该标志将prevent从调用takePicture(),而previous正在保存照片。后来在你的按钮的onClick你会检查它是否可以调用takePicture()。

  1. 声明一个标志作为活动的成员:

     私人布尔safeToTakePicture = FALSE;
     

  2. surfaceChanged(),只需设置标志设置为true调用start preVIEW()后:

      camera.start preVIEW();
    safeToTakePicture = TRUE;
     

  3. 在你的的onClick()监听器检查标志,并拍摄照片,如果OK的话:

     如果(safeToTakePicture){
        mp.start();
        camera.takePicture(NULL,NULL,mPicture);
        safeToTakePicture = FALSE;
    }
     

  4. onPictureTaken(),再次设置标志设置为true后,图像已经被保存(并添加例外打印):

      PictureCallback mPicture =新PictureCallback(){
        @覆盖
        公共无效onPictureTaken(byte []的数据,摄像头摄像头){
            PictureFile的= getOutputMediaFile();
            camera.start preVIEW();
    
            如果(PictureFile的== NULL){
                //以图片没有路,回
                safeToTakePicture = TRUE;
                返回;
            }
            尝试 {
                FileOutputStream中FOS =新的FileOutputStream(PictureFile的);
                fos.write(数据);
                fos.close();
    
            }赶上(FileNotFoundException异常E){
                e.printStackTrace(); //< --------显示异常
            }赶上(IOException异常E){
                e.printStackTrace(); //< --------显示异常
            }
    
            //保存完图片
            safeToTakePicture = TRUE;
        }
    };
     

注: 由于文档说,preVIEW必须开始前,你可以拍照。,所以可以提高将是使用一套previewCallback()注册的回调将调用当preVIEW数据是可用的,并设置标志设置为true时,在previewFrame被调用。

when i do continuous click on Capture button (without any break), getting Runtime Exception how can i resolve this issue ?

if its not possible so how may i handle this Exception ?

btnCapture = (ImageButton) findViewById(R.id.btnCapture);
                final MediaPlayer mp = MediaPlayer.create(CameraLauncherActivity.this, R.raw.button);
                btnCapture.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                            // line where getting RuntimeException
                        camera.takePicture(null, null, mPicture);   

                    }
                });

Log:

02-12 14:48:41.580: E/AndroidRuntime(6997): FATAL EXCEPTION: main
02-12 14:48:41.580: E/AndroidRuntime(6997): java.lang.RuntimeException: takePicture failed
02-12 14:48:41.580: E/AndroidRuntime(6997):     at android.hardware.Camera.native_takePicture(Native Method)
02-12 14:48:41.580: E/AndroidRuntime(6997):     at android.hardware.Camera.takePicture(Camera.java:1126)
02-12 14:48:41.580: E/AndroidRuntime(6997):     at android.hardware.Camera.takePicture(Camera.java:1071)
02-12 14:48:41.580: E/AndroidRuntime(6997):     at app.cam.shane.CameraLauncherActivity$3.onClick(CameraLauncherActivity.java:116)
02-12 14:48:41.580: E/AndroidRuntime(6997):     at android.view.View.performClick(View.java:4223)
02-12 14:48:41.580: E/AndroidRuntime(6997):     at android.view.View$PerformClick.run(View.java:17275)
02-12 14:48:41.580: E/AndroidRuntime(6997):     at android.os.Handler.handleCallback(Handler.java:615)
02-12 14:48:41.580: E/AndroidRuntime(6997):     at android.os.Handler.dispatchMessage(Handler.java:92)
02-12 14:48:41.580: E/AndroidRuntime(6997):     at android.os.Looper.loop(Looper.java:137)
02-12 14:48:41.580: E/AndroidRuntime(6997):     at android.app.ActivityThread.main(ActivityThread.java:4921)
02-12 14:48:41.580: E/AndroidRuntime(6997):     at java.lang.reflect.Method.invokeNative(Native Method)
02-12 14:48:41.580: E/AndroidRuntime(6997):     at java.lang.reflect.Method.invoke(Method.java:511)
02-12 14:48:41.580: E/AndroidRuntime(6997):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1036)
02-12 14:48:41.580: E/AndroidRuntime(6997):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:803)
02-12 14:48:41.580: E/AndroidRuntime(6997):     at dalvik.system.NativeStart.main(Native Method)

Note:- Like in Pudding Camera, they allow user to do continuous tap on Capture button, but they will never show exception, if you do 50 clicks it will capture 10 or more images, each image after specific time but not showing exception, like i am getting in my code, in a same way how can i handle this exception ?

Complete Code:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_camera);

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

            preview=(SurfaceView)findViewById(R.id.surface);     
            previewHolder=preview.getHolder();    
            previewHolder.addCallback(surfaceCallback);    
            previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

            btnCapture = (ImageButton) findViewById(R.id.btnCapture);
            final MediaPlayer mp = MediaPlayer.create(CameraLauncherActivity.this, R.raw.button);
            btnCapture.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mp.start();
                    camera.takePicture(null, null, mPicture);                 
                }
            });


    @Override
    public void onResume() {  
        super.onResume();   
        camera=Camera.open(); 
    }  

    @Override   
    public void onPause() {  
        super.onPause();  
        if (inPreview) {  
        camera.stopPreview();   
        }   
        camera.release();   
        camera=null;   
        inPreview=false;         
    }   


    private Camera.Size getBestPreviewSize(int width, int height,
            Camera.Parameters parameters) {
            Camera.Size result=null;

            for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
                if (size.width <= width && size.height <= height) {
                    if (result == null) {
                        result=size;
                    }
                    else {
                        int resultArea=result.width * result.height;
                        int newArea=size.width * size.height;

                        if (newArea > resultArea) {
                            result=size;
                        }
                    }
                }
            }

            return(result);
        }

    private Camera.Size getSmallestPictureSize(Camera.Parameters parameters) {
        Camera.Size result=null;

        for (Camera.Size size : parameters.getSupportedPictureSizes()) {
            if (result == null) {
                result=size;
            }
            else {
                int resultArea=result.width * result.height;
                int newArea=size.width * size.height;

                if (newArea < resultArea) {
                    result=size;
                }
            }
        }

        return(result);
    }


    SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback(){

    public void surfaceCreated(SurfaceHolder holder) {     
        try {        
            camera.setPreviewDisplay(previewHolder); 
            }   catch (Throwable t) {   
                Log.e("PreviewDemo-surfaceCallback",
                        "Exception in setPreviewDisplay()", t);
                Toast.makeText(CameraLauncherActivity.this, t.getMessage(), Toast.LENGTH_LONG).show();       
                }     
            }      

    public void surfaceChanged(SurfaceHolder holder,int format, int width,int height) {
        params = camera.getParameters();       
        params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
        Camera.Size size = getBestPreviewSize(width, height, params);  
        Camera.Size pictureSize=getSmallestPictureSize(params);
        if (size != null && pictureSize != null) {      
            params.setPreviewSize(size.width, size.height);
            params.setPictureSize(pictureSize.width,
                    pictureSize.height);
            camera.setParameters(params);       
            camera.startPreview();       
            inPreview=true;                 

            }     
        }      

    public void surfaceDestroyed(SurfaceHolder holder) {

        }   
    };       

    PictureCallback mPicture = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            pictureFile = getOutputMediaFile();
            camera.startPreview();
            if (pictureFile == null) {
                return;
            }
            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();
            } catch (FileNotFoundException e) {

            } catch (IOException e) {
            }
        }
    };

    static File getOutputMediaFile() {

        /* yyyy-MM-dd'T'HH:mm:ss.SSSZ */
        timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
        .format(new Date());

        // file name
        mediaFile = new File(LoginActivity.mediaStorageDir.getPath() + File.separator
                + "IMG_" + timeStamp + ".jpg");

        return mediaFile;

    }


}

解决方案

Firstly, catch your exceptions in onPictureTaken, leaving empty catch sections is not a good practice. Then, I would add a flag that would prevent from calling takePicture() while previous picture is being saved. Later in your button onClick you would check if it's ok to call takePicture().

  1. Declare a flag as a member of your Activity:

    private boolean safeToTakePicture = false;
    

  2. In surfaceChanged(), just set the flag to true after calling startPreview():

    camera.startPreview();
    safeToTakePicture = true;
    

  3. In your onClick() listener check the flag and take picture if ok to do so:

    if (safeToTakePicture) {
        mp.start();
        camera.takePicture(null, null, mPicture); 
        safeToTakePicture = false;
    }
    

  4. In onPictureTaken(), set the flag again to true after picture has been saved (and add exception printing):

    PictureCallback mPicture = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            pictureFile = getOutputMediaFile();
            camera.startPreview();
    
            if (pictureFile == null) {
                //no path to picture, return
                safeToTakePicture = true;
                return;
            }
            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();              //<-------- show exception
            } catch (IOException e) {
                e.printStackTrace();              //<-------- show exception
            }
    
            //finished saving picture 
            safeToTakePicture = true;
        }
    };
    

NOTES: As the docs say, "Preview must be started before you can take a picture.", so possible enhancement would be to use setPreviewCallback() to register callback that will be called when preview data is available, and set the flag to true when onPreviewFrame is called.

这篇关于java.lang.RuntimeException的:takePicture失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆