java.lang.Runtime中的例外:拍照失败了吗? [英] Java.lang.Runtime exception: Take Picture failed?

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

问题描述

我拍照,在里面我的Andr​​oid应用程序的背景。然而,它给出了一个错误:

I am taking pictures in the background inside my Android App. However it gives an error:

02-09 15:22:12.061: E/cheeta(28633): timer testing
02-09 15:22:13.546: W/System.err(28633): java.lang.RuntimeException: takePicture failed
02-09 15:22:13.546: W/System.err(28633):    at android.hardware.Camera.native_takePicture(Native Method)
02-09 15:22:13.546: W/System.err(28633):    at android.hardware.Camera.takePicture(Camera.java:1194)
02-09 15:22:13.551: W/System.err(28633):    at cam.sharp.MainActivity$MyTimerTask.run(MainActivity.java:69)
02-09 15:22:13.551: W/System.err(28633):    at java.util.Timer$TimerImpl.run(Timer.java:284)
02-09 15:22:13.551: E/cheeta(28633): timer testing
02-09 15:22:15.051: W/System.err(28633): java.lang.RuntimeException: takePicture failed
02-09 15:22:15.051: W/System.err(28633):    at android.hardware.Camera.native_takePicture(Native Method)
02-09 15:22:15.051: W/System.err(28633):    at android.hardware.Camera.takePicture(Camera.java:1194)
02-09 15:22:15.051: W/System.err(28633):    at cam.sharp.MainActivity$MyTimerTask.run(MainActivity.java:69)
02-09 15:22:15.051: W/System.err(28633):    at java.util.Timer$TimerImpl.run(Timer.java:284)
02-09 15:22:15.051: E/cheeta(28633): timer testing
02-09 15:22:16.551: W/System.err(28633): java.lang.RuntimeException: takePicture failed
02-09 15:22:16.556: W/System.err(28633):    at android.hardware.Camera.native_takePicture(Native Method)
02-09 15:22:16.556: W/System.err(28633):    at android.hardware.Camera.takePicture(Camera.java:1194)
02-09 15:22:16.561: W/System.err(28633):    at cam.sharp.MainActivity$MyTimerTask.run(MainActivity.java:69)
02-09 15:22:16.561: W/System.err(28633):    at java.util.Timer$TimerImpl.run(Timer.java:284)
02-09 15:22:16.561: E/cheeta(28633): timer testing

我有两个文件。

I have two files.

MainActivity.java和照相机preview.java

MainActivity.java and CameraPreview.java

下面是code两种。

MainActivity.java

package cam.sharp;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.content.Context;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.FrameLayout;
import android.widget.Toast;

public class MainActivity extends Activity {

    private int cameraId = 0;
    private Camera mCamera;
    private CameraPreview mPreview;
    String fileName = "tempImage.jpeg";
    File file;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create an instance of Camera
        mCamera = getCameraInstance(cameraId);

        if (mCamera == null) {
            Toast.makeText(
                    getApplicationContext(),
                    "The camera service is currently unavailable, please try again!",
                    Toast.LENGTH_LONG).show();
            finish();
        } else {
            // Create our Preview view and set it as the content of our
            // activity.
            mPreview = new CameraPreview(this, mCamera);
            FrameLayout frameLayout = (FrameLayout) findViewById(R.id.camera_preview);
            frameLayout.addView(mPreview);

        }

        // start thread for these

        MyTimerTask myTask = new MyTimerTask();
        Timer myTimer = new Timer();
        // public void schedule (TimerTask task, long delay, long period)
        // Schedule a task for repeated fixed-delay execution after a specific
        // delay.
        //
        // Parameters
        // task the task to schedule.
        // delay amount of time in milliseconds before first execution.
        // period amount of time in milliseconds between subsequent executions.

        myTimer.schedule(myTask, 3000, 1500);

    }

    class MyTimerTask extends TimerTask {
        public void run() {

            try {
                mCamera.takePicture(null, null, null, mPictureCallback);
                file = new File(getFilesDir(), fileName);

            } catch (Exception e) {
                e.printStackTrace();
            }

            Log.e("cheeta", "timer testing");

        }
    }

    Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] imageData, Camera c) {
            Log.e("Callback TAG", "Here in jpeg Callback");

            if (imageData != null) {
                FileOutputStream outputStream;
                try {
                    outputStream = openFileOutput(fileName,
                            Context.MODE_PRIVATE);
                    outputStream.write(imageData);
                    outputStream.close();

                    // Intent intent = new Intent(SnapScreen.this,
                    // PreviewScreen.class);
                    // if (fromMessageReview == true) {
                    // intent.putExtra("fromMessageReview", "true");
                    // }
                    // startActivity(intent);
                    // overridePendingTransition(R.anim.slide_in,
                    // R.anim.slide_out);

                    finish();
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        releaseCamera();
    }

    /** A safe way to get an instance of the Camera object. */
    public static Camera getCameraInstance(int cameraId) {
        Camera c = null;
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
                c = Camera.open(cameraId);
            } else {
                c = Camera.open();
            }
        } catch (Exception e) {
            c = null;
        }
        return c; // returns null if camera is unavailable
    }

    private void releaseCamera() {
        if (mCamera != null) {
            mCamera.release(); // release the camera for other applications
            mCamera = null;
        }
    }

}

相机preview.java

package cam.sharp;

import java.io.IOException;

import android.annotation.SuppressLint;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/** A basic Camera preview class */
@SuppressLint("ViewConstructor")
public class CameraPreview extends SurfaceView implements
SurfaceHolder.Callback {
    private static final String TAG = "Camera Preview";
    private SurfaceHolder mHolder;
    public Camera mCamera;

    @SuppressWarnings("deprecation")
    @SuppressLint("NewApi")
    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;
        mCamera.setDisplayOrientation(90);

        // 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.setDisplayOrientation(90);
                mCamera.startPreview(); 

        } catch (IOException e) {
            Log.d(TAG, "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(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }
}

有人能看到什么问题?我打电话 mCamera.start preVIEW(); ,但仍然没有用

感谢

推荐答案

您的code 2问题:

You have 2 problems in your code:

第一: onPictureTaken 叫你所呼叫的结束()返回方法至极的转向灯,该活动应该被销毁,并调用的onDestroy()方法,至极又释放你的相机。但是你的 MainActivity.java 不被破坏(不知道为什么,但通过LogCat中,我发现了的onCreate()只被调用一次,所以我认为该活动不被破坏。一种可能的解释,这可能是该定时器由diferent线程,因此控制可能不知道,MainActivity被摧毁,但我不能确认),所以你的 myTimer 将继续运行,当它到达 mCamera.takePicture(NULL,NULL,NULL,mPictureCallback); 将抛出一个 NullPointException ,因为相机已经发布,而 MainActivity.onCreate()没有再次叫了一个新的实例来mCamera。

First: In your onPictureTaken call back you are calling the finish() method, wich in turn signals that the activity should be destroyed, and calls the onDestroy() method, wich in turn releases your camera. However your MainActivity.java is not destroyed (not really sure why, but through logCat, I found that the onCreate() is only being called once, so I assumed the activity is not destroyed. A possible explanation for this might be that the Timer is controlled by a diferent thread and as such might not be aware that the MainActivity was destroyed, but I can't confirm), and so your myTimer will continue to run, and when it gets to mCamera.takePicture(null, null, null, mPictureCallback); it will throw a NullPointException because the camera was already released, and the MainActivity.onCreate() wasn't called again to get a new instance to mCamera.

因此​​,要解决的第一个问题:

So, to solve the first problem:

Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
    public void onPictureTaken(byte[] imageData, Camera c) {
        Log.e("Callback TAG", "Here in jpeg Callback");

        if (imageData != null) {
            FileOutputStream outputStream = null;
            try {
                outputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
                outputStream.write(imageData);
                // Removed the finish call you had here
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (outputStream != null) try {
                    outputStream.close();
                } catch (IOException ex) {
                    // TODO Auto-generated catch block
                    ex.printStackTrace();
                }
            }

        }
    }
};

二:是你打电话给你的启动preVIEW()方法。 Accooding到 takePicture的文档()

Second: Is where you call your startPreview() method. Accooding to the documentation of takePicture():

此方法仅在preVIEW是活动的有效(后   启动preVIEW())。 preVIEW将图像拍摄后停止;   呼叫者必须调用start preVIEW()再次,如果他们想重新开始   preVIEW或拍摄更多的照片。这不应该被间称为   启动()和stop()。

This method is only valid when preview is active (after startPreview()). Preview will be stopped after the image is taken; callers must call startPreview() again if they want to re-start preview or take more pictures. This should not be called between start() and stop().

您只调用启动preVIEW()键,当您创建摄像头,而且由于问题1,的onCreate( )上MainActivity只被调用一次。既然你有一个计时器拍照每1.5秒,你应该叫启动preVIEW()之前调用 takePicture(),所以要解决这个问题:

You were only calling startPreview() once, when you create the camera, and because of problem 1, the onCreate() on MainActivity is only being called once. Since you have a timer taking pictures every 1.5 seconds, you should call startPreview() before calling takePicture(), so to solve this:

class MyTimerTask extends TimerTask {
    public void run() {

        try {
            // Call startPreview before taking a picture
            mCamera.startPreview();
            mCamera.takePicture(null, null, null, mPictureCallback);
            file = new File(getFilesDir(), fileName);
        } catch (NullPointerException ne) {
            ne.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        Log.e("cheeta", "timer testing");

    }
}

在此应用程序continuasly拍摄照片,并将它们存储。我从来没有使用一个计时器一样,所以林不知道如何使它停下来。如果你只想要一个小数目每次调用内拍摄到图片相机preVIEW活动我建议你用一个定时器动作监听器,像这样:

After this the app continuasly takes pictures, and stores them. I never used a Timer like that so Im not sure how to make it stop. If you only want a small number of pictures taken within each call to the CameraPreview Activity I suggest you use a Timer with an action listener, like so:

Timer tm = new Timer(1000, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            // Take x pictures
            tm.stop();
        }
    });

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

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