Android 定时间隔相机触发

Android timed interval Camera triggering

我正在尝试编写一个应用程序以在给定的固定时间间隔触发 Android 相机。我正在使用 TimerTask 对其进行测试,但是我读到我不应该在 JPEG 准备好之前再次触发相机。有没有一种方法可以以固定的时间间隔触发相机,让 JPEG 在准备就绪时出现,然后再次触发它,让下一个 JPEG 在读取时出现,等等,而不会导致某种堆溢出?有没有办法做这个camera2?

以下是我目前掌握的相关方法:

PictureCallback onPicTake=new PictureCallback() {


    @Override
    public void onPictureTaken ( byte[] bytes, Camera camera){
        Log.d("data size",""+bytes.length);
        Log.d("taken", "taken");
        new SaveImageTask(getStorage()).execute(bytes);
        resetCam();

    }
};

Camera.ShutterCallback onShutter=new Camera.ShutterCallback()

{
    @Override
    public void onShutter () {
        AudioManager mgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        mgr.playSoundEffect(AudioManager.FLAG_PLAY_SOUND);

    }
};

private class CameraTrigger extends TimerTask{

      public void run(){

          mCamera.takePicture(onShutter, null, onPicTake);

      }



}
preview.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {

            timer = new Timer();
            timer.schedule(new CameraTrigger(), 0, 1000);
        }
    });
private void resetCam() {
    mCamera.startPreview();
    preview.setCamera(mCamera);
}

只要您确定 onPictureTaken() 不会超过 1000 毫秒,您的代码就没有什么大错。

我建议的一个优化是违反直觉的不是将图片保存在后台任务中,而是在回调线程中进行。

原因是 bytes 的巨大内存块无法通过这种方式轻松回收。从 JVM 的角度来看,以下模式不会给垃圾收集器带来负担:

  • 字节[] 字节 = 新字节[1Mb];
  • 填充字节
  • onPreviewFrame(字节);
  • 没有人再次需要 字节
  • 字节内存回收

但是如果有对 bytes 的未完成引用,GC 可能很难决定,您会看到 CPU 使用率的峰值,应用程序没有响应,最终,甚至 TimeTask 回调也延迟了。

请注意,在主 (UI) 线程上使用 onPictureTaken() 是不健康的。要在后台保留相机回调,您需要在辅助 Looper 线程上打开相机(请参阅此 example)。