如何在Android中现有正在运行的线程/处理程序完成后启动线程或处理程序

如何在Android中现有正在运行的线程/处理程序完成后启动线程或处理程序,android,multithreading,android-camera,android-handler,Android,Multithreading,Android Camera,Android Handler,我正在开发一个Android应用程序,用于从Front和Back相机自动捕获图像。我已经完成了从后面到前面切换相机的编码,并将捕获的图像保存到SDcard。我在手动单击按钮时测试了捕获图像,它工作得很好。我需要的是从后置摄像头自动捕获图像,然后从前置摄像头自动捕获图像。为此,我使用了handler.postDelayed()方法,但它显示java.lang.RuntimeException:takePicture失败。这里我附加了我的代码,所以任何人都请帮助我解决错误 MainActivity.

我正在开发一个
Android
应用程序,用于从
Front
Back
相机自动捕获图像。我已经完成了从后面到前面切换相机的编码,并将捕获的图像保存到
SDcard
。我在手动单击按钮时测试了捕获图像,它工作得很好。我需要的是从
后置摄像头
自动捕获图像,然后从
前置摄像头
自动捕获图像。为此,我使用了
handler.postDelayed()
方法,但它显示
java.lang.RuntimeException:takePicture失败
。这里我附加了我的代码,所以任何人都请帮助我解决错误

MainActivity.java

package com.example.camera1;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity {

       private Camera cameraObject;
       private ShowCamera showCamera;
       private ImageView pic;
       private Button takePhotoButton;
       FrameLayout preview;
       private static final ScheduledExecutorService worker = 
               Executors.newSingleThreadScheduledExecutor();
       public static Camera isCameraAvailiable(){
          Camera object = null;
          try {

             object = Camera.open(); 
          }
          catch (Exception e){
          }
          return object; 
       }

       private PictureCallback capturedIt = new PictureCallback() {

          @Override
          public void onPictureTaken(byte[] data, Camera camera) {

          Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data .length);
          if(bitmap==null){
             Toast.makeText(getApplicationContext(), "not taken", Toast.LENGTH_SHORT).show();
          }
          else
          {
             Toast.makeText(getApplicationContext(), "taken", Toast.LENGTH_SHORT).show();  

             File pictureFileDir = getDir();

            if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) {

                Log.d("", "Can't create directory to save image.");
                Toast.makeText(MainActivity.this, "Can't create directory to save image.",
                        Toast.LENGTH_LONG).show();
                return;

            }
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
            String date = dateFormat.format(new Date());
            String photoFile = "Picture_" + date + ".jpg";

            String filename = pictureFileDir.getPath() + File.separator + photoFile;

            File pictureFile = new File(filename);

            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();
                Toast.makeText(MainActivity.this, "New Image saved:" + photoFile,
                        Toast.LENGTH_LONG).show();
            } catch (Exception error) {
                Log.d("Constants.DEBUG_TAG", "File" + filename + "not saved: "
                        + error.getMessage());
                Toast.makeText(MainActivity.this, "Image could not be saved.",
                        Toast.LENGTH_LONG).show();
            }


          }

       }
    };

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

          takePhotoButton = (Button)findViewById(R.id.button_takephoto);      

          cameraObject = isCameraAvailiable();

          showCamera = new ShowCamera(this, cameraObject);
          preview = (FrameLayout) findViewById(R.id.camera_preview);
          preview.addView(showCamera);




        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                 cameraObject.takePicture(null, null, capturedIt);
            }
        }, 5000);

         cameraObject.stopPreview();    
          preview.removeView(showCamera);
        cameraObject.release();
        cameraObject = Camera.open(1);
         showCamera = new ShowCamera(MainActivity.this, cameraObject);  

          preview.addView(showCamera);

          Handler handlerFront = new Handler();
          handlerFront.postDelayed(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub


                     cameraObject.takePicture(null, null, capturedIt);
                }
            }, 5000);    





       }
       private File getDir() {
        File sdDir = Environment
                .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        return new File(sdDir, "Front&BackCamera");
    }

       @Override
       public void onPause(){
           super.onPause();
           if (cameraObject != null) {
               cameraObject.stopPreview();
               cameraObject.release();
               cameraObject = null;
            }
//         FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
              preview.removeView(showCamera);
       }

       @Override
       public void onBackPressed() {
           if (cameraObject != null) {
               cameraObject.stopPreview();
               cameraObject.release();
               cameraObject = null;
            }
           finish();
           return;
       }

       @Override
       public boolean onCreateOptionsMenu(Menu menu) {
          getMenuInflater().inflate(R.menu.activity_main, menu);
          return true;
       }
    }
package com.example.camera1;

import java.io.IOException;

import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback {

       private SurfaceHolder holdMe;
       private Camera theCamera;

       public ShowCamera(Context context,Camera camera) {
          super(context);
          theCamera = camera;
          holdMe = getHolder();
          holdMe.addCallback(this);
       }

       @Override
       public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
       }

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

       @Override
       public void surfaceDestroyed(SurfaceHolder arg0) {
           this.getHolder().removeCallback(this);
           theCamera.stopPreview(); 
           theCamera.release();
       }

    }
ShowCamera.java

package com.example.camera1;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity {

       private Camera cameraObject;
       private ShowCamera showCamera;
       private ImageView pic;
       private Button takePhotoButton;
       FrameLayout preview;
       private static final ScheduledExecutorService worker = 
               Executors.newSingleThreadScheduledExecutor();
       public static Camera isCameraAvailiable(){
          Camera object = null;
          try {

             object = Camera.open(); 
          }
          catch (Exception e){
          }
          return object; 
       }

       private PictureCallback capturedIt = new PictureCallback() {

          @Override
          public void onPictureTaken(byte[] data, Camera camera) {

          Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data .length);
          if(bitmap==null){
             Toast.makeText(getApplicationContext(), "not taken", Toast.LENGTH_SHORT).show();
          }
          else
          {
             Toast.makeText(getApplicationContext(), "taken", Toast.LENGTH_SHORT).show();  

             File pictureFileDir = getDir();

            if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) {

                Log.d("", "Can't create directory to save image.");
                Toast.makeText(MainActivity.this, "Can't create directory to save image.",
                        Toast.LENGTH_LONG).show();
                return;

            }
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
            String date = dateFormat.format(new Date());
            String photoFile = "Picture_" + date + ".jpg";

            String filename = pictureFileDir.getPath() + File.separator + photoFile;

            File pictureFile = new File(filename);

            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();
                Toast.makeText(MainActivity.this, "New Image saved:" + photoFile,
                        Toast.LENGTH_LONG).show();
            } catch (Exception error) {
                Log.d("Constants.DEBUG_TAG", "File" + filename + "not saved: "
                        + error.getMessage());
                Toast.makeText(MainActivity.this, "Image could not be saved.",
                        Toast.LENGTH_LONG).show();
            }


          }

       }
    };

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

          takePhotoButton = (Button)findViewById(R.id.button_takephoto);      

          cameraObject = isCameraAvailiable();

          showCamera = new ShowCamera(this, cameraObject);
          preview = (FrameLayout) findViewById(R.id.camera_preview);
          preview.addView(showCamera);




        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                 cameraObject.takePicture(null, null, capturedIt);
            }
        }, 5000);

         cameraObject.stopPreview();    
          preview.removeView(showCamera);
        cameraObject.release();
        cameraObject = Camera.open(1);
         showCamera = new ShowCamera(MainActivity.this, cameraObject);  

          preview.addView(showCamera);

          Handler handlerFront = new Handler();
          handlerFront.postDelayed(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub


                     cameraObject.takePicture(null, null, capturedIt);
                }
            }, 5000);    





       }
       private File getDir() {
        File sdDir = Environment
                .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        return new File(sdDir, "Front&BackCamera");
    }

       @Override
       public void onPause(){
           super.onPause();
           if (cameraObject != null) {
               cameraObject.stopPreview();
               cameraObject.release();
               cameraObject = null;
            }
//         FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
              preview.removeView(showCamera);
       }

       @Override
       public void onBackPressed() {
           if (cameraObject != null) {
               cameraObject.stopPreview();
               cameraObject.release();
               cameraObject = null;
            }
           finish();
           return;
       }

       @Override
       public boolean onCreateOptionsMenu(Menu menu) {
          getMenuInflater().inflate(R.menu.activity_main, menu);
          return true;
       }
    }
package com.example.camera1;

import java.io.IOException;

import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback {

       private SurfaceHolder holdMe;
       private Camera theCamera;

       public ShowCamera(Context context,Camera camera) {
          super(context);
          theCamera = camera;
          holdMe = getHolder();
          holdMe.addCallback(this);
       }

       @Override
       public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
       }

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

       @Override
       public void surfaceDestroyed(SurfaceHolder arg0) {
           this.getHolder().removeCallback(this);
           theCamera.stopPreview(); 
           theCamera.release();
       }

    }
LogCat输出

05-30 15:22:07.102: E/AndroidRuntime(7629): FATAL EXCEPTION: main
05-30 15:22:07.102: E/AndroidRuntime(7629): java.lang.RuntimeException: takePicture failed
05-30 15:22:07.102: E/AndroidRuntime(7629):     at android.hardware.Camera.native_takePicture(Native Method)
05-30 15:22:07.102: E/AndroidRuntime(7629):     at android.hardware.Camera.takePicture(Camera.java:1233)
05-30 15:22:07.102: E/AndroidRuntime(7629):     at android.hardware.Camera.takePicture(Camera.java:1178)
05-30 15:22:07.102: E/AndroidRuntime(7629):     at com.example.camera1.MainActivity$2.run(MainActivity.java:176)
05-30 15:22:07.102: E/AndroidRuntime(7629):     at android.os.Handler.handleCallback(Handler.java:615)
05-30 15:22:07.102: E/AndroidRuntime(7629):     at android.os.Handler.dispatchMessage(Handler.java:92)
05-30 15:22:07.102: E/AndroidRuntime(7629):     at android.os.Looper.loop(Looper.java:153)
05-30 15:22:07.102: E/AndroidRuntime(7629):     at android.app.ActivityThread.main(ActivityThread.java:5086)
05-30 15:22:07.102: E/AndroidRuntime(7629):     at java.lang.reflect.Method.invokeNative(Native Method)
05-30 15:22:07.102: E/AndroidRuntime(7629):     at java.lang.reflect.Method.invoke(Method.java:511)
05-30 15:22:07.102: E/AndroidRuntime(7629):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:821)
05-30 15:22:07.102: E/AndroidRuntime(7629):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584)
05-30 15:22:07.102: E/AndroidRuntime(7629):     at dalvik.system.NativeStart.main(Native Method)

通过移动,您可以轻松地重写代码

     cameraObject.stopPreview();    
      preview.removeView(showCamera);
    cameraObject.release();
    cameraObject = Camera.open(1);
     showCamera = new ShowCamera(MainActivity.this, cameraObject);  

      preview.addView(showCamera);

      Handler handlerFront = new Handler();
      handlerFront.postDelayed(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub


                 cameraObject.takePicture(null, null, capturedIt);
            }
        }, 5000);    
要使用另一个方法,请调用它
MainActivity.takeSecondPictureAfterDelay()
。现在,不是从
MainActivity.OnCeate()
,而是从
onPictureTaken()
——在处理第一张图片的所有工作完成后,调用此方法

要做的重要更改:您需要一些机制来检查此方法是否只被调用一次。例如,添加

private int picturesTaken = 0;
onPictureTaken()
——方法的最开始——添加

现在您可以进行一些清理,例如,不需要使用来分离
处理程序
s。您可以对两张图片重复使用相同的处理程序,甚至可以使用
showCamera.postDelayed()
而不是
handlerXXX.postDelayed()