Android 调用前置摄像头

转自:http://www.cnblogs.com/stay/archive/2011/06/24/2089129.html

首先,鄙人要发泄下对Android小小的不满,为神马2.3才有api来支持front Camera ,为神马2.3之前的版本也会有前置摄像头,为神马每个厂商的调用前置摄像头的方式都不一样。尼玛同样是写程序,至于搞那么多不同版本不同兼容性问题么。生物识别技术你们伤不起啊!!!GOOGLE 您神马时候才能统一啊!!!别折磨我们这群蛋疼的码农了。该死的魂淡厂商们,你们大致统一一下行不行,坑爹的。

if(model.equals(SUMSUNG&HTC&MOTO)){system.exit(0)}//支持山寨。

先说如何录频吧。最简单的,调用MediaRecorder,最好开个子线程去写:

这里网上有很多帖子都说,有bug,问题出在编码上,因为每个厂商支持的视频编码有点差异,所以别指望同一个代码能支持所有的手机。我用H264测试了十部手机,

9个通过,1个坑爹的HTC 野火不支持。所以还是使用DEFAULT吧。MediaRecorder.VideoEncoder.DEFAULT

 Runnable run = new Runnable() {
  public void run() {
   try {
    myRecAudioFile = new File(Environment.getExternalStorageDirectory(), "video.mp4");// 创建临时文件
    if (myRecAudioFile.exists()) {
     myRecAudioFile.delete();
    }
    myRecAudioFile.createNewFile();
    recorder.reset();
    recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);// 视频源
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 录音源为麦克风
    recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// 输出格式为mp4
    recorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);// 视频编码
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);// 音频编码
    recorder.setVideoFrameRate(15);// 视频帧频率
    recorder.setVideoSize(320, 240);// 视频尺寸
    recorder.setPreviewDisplay(mSurfaceHolder.getSurface());// 预览
    // recorder.setMaxDuration(10000);// 最大期限
    recorder.setOutputFile(myRecAudioFile.getAbsolutePath());// 保存路径
    recorder.prepare();
    recorder.start();
    mHandler.sendEmptyMessageDelayed(1, 10000);
   } catch (Exception e) {
    stop(true);
   }
  }
 };

现在来说前置摄像的问题

2.3的api调用前置非常easy

Camera  android.hardware. Camera .open(int cameraId)

Creates a new Camera object to access a particular hardware camera.

cameraId the hardware camera to access, between 0 and  getNumberOfCameras()-1.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
   for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
    CameraInfo info = new CameraInfo();
    Camera.getCameraInfo(i, info);
    if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {//这就是前置摄像头,亲。
     c = Camera.open(i);
    }
   }
  }
  if (c == null) {
   c = Camera.open();
  }

  c.unlock();//注意,要在MediaRecorder设置参数之前就调用unlock来获得camera的控制权。camera是单例的嘛。如果不调用,程序就挂
  recorder.setCamera(c);

void android.hardware. Camera.unlock()

Unlocks the camera to allow another process to access it. Normally, the camera is locked to the process with an active Camera object until release() is called. To allow rapid handoff between processes, you can call this method to release the camera temporarily for another process to use; once the other process is done you can call reconnect() to reclaim the camera.

This must be done before calling android.media.MediaRecorder.setCamera(Camera).

If you are not recording video, you probably do not need this method.

这样就大功告成了。最后还有要注意的地方,就是当你停止拍摄或程序down掉的时候,要调用camera.lock()来释放camera的控制权,否则就不能再开启camera。知道抛异常。

private void stop(boolean force) {
  if (!force) {
   recorder.stop();
  }
  recorder.reset();
  recorder.release();
  recorder = null;
  if (c != null) {
   c.lock();
   c.release();
   c = null;
  }
  setResult(force ? Activity.RESULT_CANCELED : Activity.RESULT_OK);

//还记得,调用系统的camera来拍照时,intent里会返回文件的uri。你也可以这样做   intent.setData(Uri.fromFile(tempFile))
  this.finish();
 }

下面再来说2.3之前的如何调用前置的。公司只有HTC野火和SUMSUNG I9000有前置,所以我只研究了这两个,有其他brand的可以用类似的方法去做,如果你弄出来了,请告诉我,mark下

debug还是比较有趣的事情,我是指能成功的debug的话。。。。。

测试这两个手机的时候我一行一行的看log。眼睛都花了,一遍咒骂宏达电和三星。

06-23 17:49:05.058: WARN/CameraService(2374): getParameters(AppShutterSound=0;anti-shake=0;antibanding=auto;antibanding-values=auto,50hz,60hz,off;beauty-shot=0;blur=0;camera-id=1;chk_dataline=0;contrast=2;contrast-max=4;contrast-min=0;effect=none;effect-values=none,mono,negative,sepia;exposure-compensation=0;exposure-compensation-step=0.5;focal-length=3.79;focus-mode=auto;focus-mode-values=auto,macro;horizontal-view-angle=51.2;iso=auto;jpeg-quality=100;jpeg-thumbnail-height=120;jpeg-thumbnail-quality=100;jpeg-thumbnail-size-values=160x120,0x0;jpeg-thumbnail-width=160;max-exposure-compensation=4;max-zoom=30;metering=center;min-exposure-compensation=-4;picture-format=jpeg;picture-format-values=jpeg;picture-size=2560x1920;picture-size-values=2560x1920,2048x1536,1600x1200,640x480,2560x1536,2048x1232,1600x960,800x480;preview-format=yuv420sp;preview-format-values=yuv420sp;preview-frame-rate=30;preview-frame-rate-values=15,30;preview-size=640x480;preview-size-values=320x240,640x480,800x480;rotation=0;saturation=2;saturation-max=4;saturation-min=0;scene-mode=au

这是三星的Camera.Parameters         你觉得哪个是设置前置摄像头的么    camera-id=1   bingo   就是它了。

//  Parameters parameters = c.getParameters();
//  parameters.set("camera-id",2);//sumsung 2.3以前的手机     我的I9000成功设置成前置的了。

06-23 18:14:50.697: DEBUG/CameraService(1622): getParameters(Make=HTC;antibanding=auto;antibanding-values=auto,50hz,60hz;brightness=0;brightness-def=0;brightness-max=20;brightness-min=-20;contrast=0;contrast-def=0;contrast-max=100;contrast-min=-100;device=;device-list=/dev/video0,/dev/video1,/dev/video2;effect=none;effect-values=none,mono,negative,sepia,aqua;exposure-compensation=0;exposure-compensation-step=0;fnumber=3.5;focal-length=2.76;focus-mode=auto;focus-mode-values=auto;gps-mapdatum=WGS 84;horizontal-view-angle=54;iso=auto;jpeg-quality=85;jpeg-thumbnail-height=240;jpeg-thumbnail-size-values=320x240,0x0;jpeg-thumbnail-width=320;max-exposure-compensation=0;max-zoom=10;meter-mode=meter-average;min-exposure-compensation=0;models=A3360;picture-format=jpeg;picture-format-values=jpeg;picture-size=2048x1536;picture-size-values=2048x1536,1600x1200,1280x1024,1280x960,1024x768,800x600,640x480,384x288,352x288,320x240,176x144;preview-format=yuv420sp;preview-format-values=yuv420sp;preview-frame-rate=15;preview-frame-rate-values=30,15;preview-size=320x240;previ

好了,这是宏达电的,你猜哪个是?   不好意思,木有这个参数。当时我就郁闷了。Android程序员你们都伤不起啊。一堆的兼容性问题。尼玛你们来试试。

肿么办,好吧,去看系统自带的Camera吧,如果你懂得观察,还是比较有意思的。野火的后置摄像头叫  (主)   你们有这个机器的可以自己测试下。

06-23 18:14:50.716: DEBUG/CameraService(1622): setParameters: video_input= main(有意思吧)

debug吧,坑爹的叫video_input    尼玛弄不一样的key有意思么,搞这么混乱让人肿么活。人家做爱疯的,从底层自己写上来,一遍就ok啦。有木有。我们有一大堆的api,半小时就能写出来的功能,debug就要几天。有木有!!!

你再试试吧系统的Camera切换成副摄像头叫什么。。。Secondary。有木有!!!

好吧。video_input= Secondary    去试吧。依旧不行。。。S小写。尼玛伤不起啊

//  Parameters parameters = c.getParameters();

//  parameters.set("camera-id",2);//sumsung 2.3以前的手机  前置

//  parameters.set("camera-id",1);//sumsung 2.3以前的手机  后置

//  parameters.set("video_input","secondary");//htc2.3以前的手机  前置

//  parameters.set("video_input","main");//htc2.3以前的手机   后置

//  c.setParameters(parameters);

ok,都这里就全部结束了。蛋疼的debug。蛋疼的Android。蛋疼的人生。码农你们伤不起啊!!!!


你可能感兴趣的:(Android 调用前置摄像头)