【问题标题】:Android Studio: takePicture errorAndroid Studio:拍照错误
【发布时间】:2017-02-27 03:05:38
【问题描述】:

我对 Android Studio 中的 takePicture(); 方法有疑问。 我看过很多教程,但没有一个对我有帮助。请帮助我:0 这是我的代码:

Button button;
Camera cam = null;

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

    cam = Camera.open();

    button = (Button) findViewById(R.id.getrange);

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            cam.startPreview();
            cam.takePicture(null, null, null, mPicture);
        }
    });

}

public static Camera.PictureCallback mPicture = new Camera.PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        File dir = new File(Environment.getExternalStorageDirectory(), "Bewegungsmelder-App");
        dir.mkdirs();

        File file = new File(dir, "IMG_" + System.currentTimeMillis() + ".jpg");

        if (file == null) {
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }
    }
};

@Override
protected void onPause() {
    super.onPause();

    cam.stopPreview();
    cam.release();
    cam = null;
}

@Override
protected void onResume() {
    super.onResume();

    cam = Camera.open();
}

清单权限

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

这里是错误代码

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: degaming.bewegungsmelder, PID: 12580
              java.lang.RuntimeException: takePicture failed
                  at android.hardware.Camera.native_takePicture(Native Method)
                  at android.hardware.Camera.takePicture(Camera.java:1711)
                  at degaming.bewegungsmelder.MainActivity$1.onClick(MainActivity.java:36)
                  at android.view.View.performClick(View.java:5642)
                  at android.view.View$PerformClick.run(View.java:22338)
                  at android.os.Handler.handleCallback(Handler.java:751)
                  at android.os.Handler.dispatchMessage(Handler.java:95)
                  at android.os.Looper.loop(Looper.java:154)
                  at android.app.ActivityThread.main(ActivityThread.java:6209)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

感谢您的帮助 D:
PS:Bewegungsmelder 是德国人。这意味着运动检测器!

【问题讨论】:

  • This 会为您的问题提供简单易用的解决方案
  • 拍完第二张还是第一张之后会出现这种情况吗?
  • @ChrisGong 第一次就发生了
  • @DEGaming 检查我的编辑

标签: java android camera


【解决方案1】:

除了在您的onClick 中调用之外,在您的onPictureTaken 方法中调用startPreview

public static Camera.PictureCallback mPicture = new Camera.PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        File dir = new File(Environment.getExternalStorageDirectory(), "Bewegungsmelder-App");
        dir.mkdirs();

        File file = new File(dir, "IMG_" + System.currentTimeMillis() + ".jpg");
        if (file == null) {
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }
        camera.startPreview();
    }
};

原因是一旦你拍照,当前的预览就被破坏了,所以下次你拍照时需要重新开始。

编辑: 除了在调用takePicture 之前调用startPreview 之外,您忘记的另一件重要的事情是,根据Android documentation point #5,您没有将surfaceHolder 传递给@ 987654329@。首先,将 SurfaceView 添加到您的 XML 布局并将 id 设置为preview。其次,在类的顶部添加一个SurfaceHolder 变量和一个SurfaceView 变量,

SurfaceHolder surfaceHolder;
SurfaceView surfaceView;

然后在你的onCreate中,像这样初始化变量,

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

现在,为surfaceHolder 进行回调,

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

    public void surfaceCreated(SurfaceHolder holder) {     
        try {        
            cam.setPreviewDisplay(surfaceHolder); 
        } catch (Throwable t) {   

        }     
    }      

    public void surfaceChanged(SurfaceHolder holder,int format, int width,int height) {
        Camera.Parameters params = cam.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);
            cam.setParameters(params);       
            cam.startPreview();                      

        }     
    }      

    public void surfaceDestroyed(SurfaceHolder holder) {
        cam.stopPreview();
    }   
};

毕竟,我认为您不需要在您的onClick 中调用startPreview。但是,我认为为了使其工作,您可能必须使 cam 成为静态变量以及其他变量。对此不是 100% 确定的。

【讨论】:

  • @DEGaming 第一次单击按钮时会发生这种情况吗?它有没有到相机屏幕打开的地步?
  • 第一次发生
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多