0

免责声明:我是 Android 开发的新手我正在尝试构建一个 android 应用程序,它可以每 X 秒单击一次照片,而无需用户多次单击该按钮。用户只需单击按钮即可停止计时器。我阅读了此问题的以下答案,但我对 Timer 代码的去向感到困惑。我已经实现了以下代码:

MyCamera.java 文件

public class MyCamera extends AppCompatActivity {

private Camera mCamera;
private CameraPreview mCameraPreview;
private FrameLayout preview;
Timer timer;
TimerTask timerTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my_camera);

    Button cancel = (Button) findViewById(R.id.cancel);
    //Button captureButton = (Button) findViewById(R.id.button_capture);
    //captureButton.setOnClickListener();
}

protected void onResume(){
    super.onResume();
    mCamera = getCameraInstance();
    mCameraPreview = new CameraPreview(this,mCamera);
    preview = (FrameLayout) findViewById(R.id.camera_preview);
    preview.addView(mCameraPreview);
    timer = new Timer();
    startTimer();
}

/*
protected void onPause(){
    super.onPause();
    if(mCamera != null){
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }
    if(mCameraPreview != null){
        preview.removeView(mCameraPreview);
        mCameraPreview = null;
    }
}
*/

public void startTimer(){

    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            mCamera.startPreview();
            mCamera.takePicture(null,null,mPicture);
        }
    },5000,5000);
}

public void stopTimerTask(View v){
    if(timer!=null){
        timer.cancel();
        timer = null;
    }
}

private Camera getCameraInstance(){
    Camera camera = null;
    try{
        camera = Camera.open();
    }catch(Exception e){
        e.printStackTrace();
    }
    return camera;
}

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

private static File getOutputMediaFile(){
    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"MyCameraApp");
    //File mediaStorageDir = new File(Environment.getExternalStorageDirectory()+File.separator);

    if(!mediaStorageDir.exists()){
        if(!mediaStorageDir.mkdirs()){
            Log.d("MyCameraApp","failed to create directory");
            return null;
        }
    }

    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File mediaFile;
    mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
    return mediaFile;
}


private boolean checkCameraHardware(Context context){
    if(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
        return true;
    }
    else{
        return false;
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_my_camera, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

}

CameraPreview.java 文件

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;

@SuppressWarnings("deprecation")
public CameraPreview(Context context, Camera camera){
    super(context);
    this.mCamera = camera;
    this.mSurfaceHolder = this.getHolder();
    this.mSurfaceHolder.addCallback(this);
    this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

@Override
public void surfaceCreated(SurfaceHolder surfaceHolder){
    try{
        mCamera.setPreviewDisplay(surfaceHolder);
        mCamera.setDisplayOrientation(90);
        mCamera.startPreview();
    }catch(IOException e){
        e.printStackTrace();
    }
}

@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder){
    mCamera.stopPreview();
    mCamera.release();
}

@Override
public void surfaceChanged(SurfaceHolder surfaceHolder,int format,int width,int height){
    try{
        mCamera.setPreviewDisplay(surfaceHolder);
        mCamera.startPreview();
    } catch (Exception e){
        e.printStackTrace();
    }
}

}

布局文件

<FrameLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/camera_preview"
    android:layout_weight="1" />

<Button
    android:id="@+id/cancel"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="stopTimerTask"
    android:text="Cancel"/>

我还包括了相机和写入外部存储设备的权限。

我得到这个作为我的错误日志:

java.lang.RuntimeException: Method called after release()
        at android.hardware.Camera.startPreview(Native Method)
        at com.akshitk.cameraapp.MyCamera$1.run(MyCamera.java:72)
        at java.util.Timer$TimerImpl.run(Timer.java:284)

我可以拍一张照片,然后应用程序崩溃。有人可以告诉我哪里出错了吗?

4

0 回答 0