免责声明:我是 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)
我可以拍一张照片,然后应用程序崩溃。有人可以告诉我哪里出错了吗?