检测摄像头 插入和拔出状态,给出提示。当重新插入摄像头时,init camera


之前打算通过USB的广播事件来检测摄像头插拔。网上的资料显示可以通过
Receive  系统的ACTION_MEDIA_MOUNTED事件。尝试没成功



最终采取了以下这种方案,但是不停检测必然存在效率问题

(1)因为带有Camera的Activity,实现了PreviewCallback接口。
需要Override一个方法:public void onPreviewFrame(byte[] arg0, Camera arg1)
此方法,在Camera工作的时候,是不停的进行调用的。
我们将摄像头拔出事件的检测,放在了这个方法中。对摄像头拔出事件的检测,简单定义为:
2秒之内onPreviewFrame方法没有执行,定义为摄像头故障。
一旦方法被执行,此计时取消,新建一个计时器,重新进行计时。

因此,使用的是以下schedule方法:
timerCameraDetached.schedule(cameraDetachedtask,mCameraDetachedDelay);
即:
mCameraDetachedDelay之后执行,只执行一次



(2)在认定摄像头拔出之后,发送一个CAMERA_DETACHED的Message给Handler
此时,将Camera destroy掉,并设空,将装载Camera的容器中的View remove掉。
然后开始检测摄像头插入事件。
而对摄像头插入事件的检测,定义为:
每1秒,检测一次摄像头数量。什么时候数量大于0,则摄像头插入。然后进行摄像头的初始化
使用的是以下schedule方法:
timerCameraAttached.schedule(cameraAttachedtask,0,mCameraAttachedPeriod); //start detecting,loop
即:反复执行,0代表无延迟立即执行,执行周期为mCameraAttachedPeriod(1秒)。
只有当摄像头数量大于0的时候,才发送CAMERA_ATTACHED的Message给Handler

一、CameraStateDetector.java 用来检测当前camera状态
3 import java.util.Timer; 4 import java.util.TimerTask; 5 6 import android.content.Context; 7 import android.graphics.ImageFormat; 8 import android.hardware.Camera; 9 import android.hardware.Camera.PreviewCallback; 10 import android.os.Handler; 11 import android.os.Message; 12 import android.view.Gravity; 13 import android.widget.FrameLayout; 14 15 import com.github.snowdream.android.util.Log; 20 21 public class CameraStateDetector { 22 23 /** 24 * Timer to detect camera detached event 25 */ 26 private final int CAMERA_DETACHED = 1;    //用于Handler 27 private final int CAMERA_ATTACHED = 2; 28 private int mCameraDetachedDelay = 2000;  //拔出事件,隔2秒检测一次 29 private int mCameraAttachedPeriod = 1000;  //插入事件,隔1秒检测一次 30 public Timer timerCameraAttached;  //检测摄像头插入事件的计时器 31 public Timer timerCameraDetached;  //检测摄像头拔出事件的计时器 32 private boolean isCameraWork=false;    //摄像头是否工作的标识 33 34 private Context mContext; 35 private CameraWrapper mCamera; 36 private FrameLayout mCameraContainer;  //Camera的容器, 对不同状态做出相应改变 37 private CameraConfig mCameraConfig; 38 39 public CameraStateDetector(Context context,CameraWrapper camera,FrameLayout cameraContainer,CameraConfig cameraConfig){ 40 mContext = context; 41 mCamera = camera; 42 mCameraContainer = cameraContainer; 43 mCameraConfig = cameraConfig; 44 } 45 46 public Handler mCameraHandler = new Handler(){ 47 public void handleMessage(Message msg) { 48 switch (msg.what) { 49 case CAMERA_DETACHED: 50 if(isCameraWork == true){ 51 isCameraWork = false; 52 } 53 54 //show toast 55 showToast(mContext.getString(R.string.incall_camera_detached)); 56 //remove camera 57 mCameraContainer.removeAllViews(); 58 // stop camera 59 if (mCamera != null) { 60 mCamera.destroy(); 61 mCamera = null; 62 } 63 startDetectCameraAttachEvent(); 64 65 break; 66 67 case CAMERA_ATTACHED: 68 Log.d(LogConfig.CALL_TAG, "camera work "); 69 if(isCameraWork == false){ 70 isCameraWork = true; 71 } 72 showToast(mContext.getString(R.string.incall_camera_attached)); 73 initCamera(); 74 75 if(timerCameraAttached !=null) 76 timerCameraAttached.cancel(); 77 78 break; 79 } 80 super.handleMessage(msg); 81 } 82 83 }; 84 85 /*** 86 * Init local camera     初始化Camera。add得到container中 87 */ 88 public void initCamera() { 89 Log.d(LogConfig.CALL_TAG, "init camera InCallActivity"); 90 if (Camera.getNumberOfCameras() == 0) { 91 Log.e(LogConfig.CALL_TAG, "no camera found"); 92 startDetectCameraAttachEvent(); 93 } else { 94 mCameraConfig = new CameraConfig(); 95 mCameraConfig.facing = 0; 96 mCameraConfig.format = ImageFormat.NV21; 97 mCameraConfig.fps = CallConstant.DEFAULT_FPS_NUM; 98 mCameraConfig.width = CallConstant.DEFAULT_WIDTH; 99 mCameraConfig.height = CallConstant.DEFAULT_HEIGHT; 100 mCamera = new CameraWrapper(mContext, (PreviewCallback)mContext, mCameraConfig); 101 102 mCameraContainer.addView(mCamera); 103 Log.e(LogConfig.CALL_TAG, "add camera"); 104 } 105 } 106 107 //检测摄像头拔出的事件。因为把这个事件,放在Pre 108 public void startDetectCameraDettachEvent() { 109 if(timerCameraAttached !=null)    //先取消“摄像头插入事件"的检测 110 timerCameraAttached.cancel(); 111 112 //detecting camera detached event 113 TimerTask cameraDetachedtask = new TimerTask() {  //过mCameraDetachedDelay时间之后,发送一个CAMERA_DETACHED的消息 114 @Override 115 public void run() { 116 Message message = new Message(); 117 message.what = CAMERA_DETACHED; 118 mCameraHandler.sendMessage(message); 119 } 120 }; 121 122 123 //init camera dettach detecting timer 124 if(timerCameraDetached !=null)      //如果当前有“摄像头拔出事件"的检测,先停掉 125 timerCameraDetached.cancel(); 126 timerCameraDetached = new Timer();    //新建一个计时操作

       //mCameraDetachedDelay之后开始运行。且只运行一次
127 timerCameraDetached.schedule(cameraDetachedtask,mCameraDetachedDelay);   128 } 129 130 public void startDetectCameraAttachEvent() { 131 //stop camera detached detecting timer 132 if(timerCameraDetached !=null) 133 timerCameraDetached.cancel(); 134 //define new timer task. when number of camera > 0, send message 135 TimerTask cameraAttachedtask = new TimerTask() { 136 @Override 137 public void run() { 138 Log.d(LogConfig.IN_CALL_TAG, "camera number :"+Camera.getNumberOfCameras()); 139 if(Camera.getNumberOfCameras() > 0){ 140 Message message = new Message(); 141 message.what = CAMERA_ATTACHED; 142 mCameraHandler.sendMessage(message); 143 } 144 } 145 }; 146 147 148 //init camera attached detecting timer 149 if(timerCameraAttached !=null) 150 timerCameraAttached.cancel(); 151 timerCameraAttached = new Timer(); 152 timerCameraAttached.schedule(cameraAttachedtask,0,mCameraAttachedPeriod); //start detecting,loop 153 } 154 155 156 157 public boolean isCameraWork() { 158 return isCameraWork; 159 } 160 161 162 public void setCameraWork(boolean isCameraWork) { 163 this.isCameraWork = isCameraWork; 164 } 165 166 167 public void showToast(String str) { 168 ToastView toast = ToastView.getInstance(mContext); 169 toast.showToast(str, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 170 (int) mContext.getResources() 171 .getDimension(R.dimen.defaultToastMarginTop)); 172 } 173 174 }

 

 

 

 

二、Activity中调用

 

  1 import java.util.List;
  2 
  3 import android.app.Activity;
  4 import android.content.BroadcastReceiver;
  5 import android.content.Context;
  6 import android.content.Intent;
  7 import android.content.IntentFilter;
  8 import android.graphics.ImageFormat;
  9 import android.hardware.Camera;
 10 import android.hardware.Camera.PreviewCallback;
 11 import android.os.Bundle;
 12 import android.os.Handler;
 13 import android.support.v4.content.LocalBroadcastManager;
 14 import android.text.TextUtils;
 15 import android.view.KeyEvent;
 16 import android.view.View;
 17 import android.view.ViewGroup;
 18 import android.view.Window;
 19 import android.view.WindowManager;
 20 import android.widget.AdapterView;
 21 import android.widget.AdapterView.OnItemClickListener;
 22 import android.widget.BaseAdapter;
 23 import android.widget.FrameLayout;
 24 import android.widget.ImageView;
 25 import android.widget.Toast;
 26 
 27 import com.github.snowdream.android.util.Log;
 28 
 29 
 30 public class CallActivity extends Activity implements PreviewCallback {
 31     //A frame to show self camera
 32     private FrameLayout mCallSelfCameraContainer;
 33
 34     private CameraConfig mCameraConfig;
 35     private CameraWrapper mCamera;
 38     
 39     //a detector to detect camera USB state
 40     private CameraStateDetector mCameraStateDetector;
 41 
 42     @Override
 43     protected void onCreate(final Bundle savedInstanceState) {
 44         super.onCreate(savedInstanceState);
 45         // Remove title bar
 46         this.requestWindowFeature(Window.FEATURE_NO_TITLE);
 47 
 48         // Remove notification bar
 49         this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
 50                 WindowManager.LayoutParams.FLAG_FULLSCREEN);
 51         setContentView(R.layout.call_activity);
54 mCameraStateDetector = new CameraStateDetector(this, mCamera,mCallSelfCameraContainer, mCameraConfig); 55 56 initCamera(); 57 } 58 59 private void initCamera() { 60 61 if (Camera.getNumberOfCameras() == 0) { 62 Log.e(LogConfig.CALL_TAG, "no camera found"); 63 mCameraStateDetector.startDetectCameraAttachEvent(); //如果第一次初始化的时候,没检测到摄像头,就开始检测摄像头插入事件了 64 65 }else{ 66 mCameraConfig = new CameraConfig(); 67 mCameraConfig.facing = 0; 68 mCameraConfig.format = ImageFormat.NV21; 69 mCameraConfig.fps = CallConstant.DEFAULT_FPS_NUM; 70 mCameraConfig.width = CallConstant.DEFAULT_WIDTH; 71 mCameraConfig.height = CallConstant.DEFAULT_HEIGHT; 72 mCamera = new CameraWrapper(this, this, mCameraConfig); 73 74 mCallSelfCameraContainer.addView(mCamera); 75 } 76 } 77 78 private void findViews() { 81 mCallSelfCameraContainer = (FrameLayout) findViewById(R.id.callSelfCameraContainer); 83 } 84 85 @Override 86 public void onPreviewFrame(byte[] arg0, Camera arg1) { 87 mCameraStateDetector.setCameraWork(true);     88 mCameraStateDetector.startDetectCameraDettachEvent(); //检测摄像头拔出事件 89 } 91 92 93 @Override 94 protected void onDestroy() { 95 super.onDestroy(); 96 97 mCallSelfCameraContainer.removeAllViews(); 98 //stop camera 99 if (mCamera != null) { 100 mCamera.destroy(); 101 mCamera = null; 102 } 103 104 if(mCameraStateDetector.timerCameraAttached !=null){ 105 mCameraStateDetector.timerCameraAttached.cancel(); 106 } 107 108 if(mCameraStateDetector.timerCameraDetached !=null){ 109 mCameraStateDetector.timerCameraDetached.cancel(); 110 } 111 } 113 }

 

posted @ 2014-12-17 16:24  马小豆包  阅读(1606)  评论(0编辑  收藏  举报