Android Camera应用开发小结

 


       近期做了一段时间的Camera的开发,虽然是应用层的开发但是也粗略的接触了一些framework相关的东西,在此写出来分享下。
       先说下应用开发的目的和实用环境,这次开发的主要目的是实现android设备上外挂USB摄像头来实现录像拍照的功能,类似行车记录仪的功能,但是灵活性更大因为可随时在android设备上回看录像和回看照片,并可查看GPS的运行轨迹,当然主要功能还是录像和拍照功能了。</p><p>     首先还是要做一个简单的demo功能出来,后面再逐渐的去丰富各个功能模块和完善BUG。
       第一步肯定是建工程了,一个主Activity用来显示录像预览的图像,并且设计简单的按钮分别来实现开始关闭录像,拍照,浏览录像和照片等功能。      当然首先还是要在AndroidManifest.xml中加入 

       <uses-permission android:name = "android.permission.CAMERA" /> 
      <uses-feature android:name = "android.hardware.camera" /> 
      <uses-feature android:name = "android.hardware.camera.autofocus" /> 
      <uses-permission android:name = "android.permission.RECORD_AUDIO"></span>

 

      之所以加入RECORD_AUDIO是因为后期可能会加入声音录入,因此提前加进来。

        主Activity需要实现OnClickListener,SurfaceHolder.Callback,OnCheckChangeListener等接口,因为所设计的按钮分别需要监听Click,录像模式选择会监听CheckBox的动作。

       核心代码

               下面的函数主要是实现Camera取景预览的界面,并且初始化了应用的初始界面,包括按钮和预览界面。

                    取景的容器为SurfaceView,使用它必须用到SurfaceHolder,它可以随时监听Surface的变化。并且需要将SurfaceHolder的类型设置为SURFACE_TYPE_PUSH_BUFFERS.这样画面缓存会由Camera类来管理。

              
	private void initView() {
		display = (SurfaceView) findViewById(R.id.display);
		surfaceHolder = display.getHolder();
		surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

		camera = (ImageButton) findViewById(R.id.camera);
		video_record = (CheckBox) findViewById(R.id.video);
		camera_shoot = (ImageButton) findViewById(R.id.shoot);
		
		explorer = (Button) findViewById(R.id.explorer);
		settings = (Button) findViewById(R.id.settings);
                                         
		surfaceHolder.addCallback(this);
		surfaceHolder.setFormat(PixelFormat.TRANSPARENT);
		surfaceHolder.setFixedSize(1280,720);
		camera.setOnClickListener(this);
		camera_shoot.setOnClickListener(this);
		
		explorer.setOnClickListener(this);
		settings.setOnClickListener(this);
		timer = (TextView)findViewById(R.id.timer);

                  video_record.setOnClickListener(this);
	}

          Camera录像拍照等功能我实现均在另一个Service中,目的也是可以实现后台录像的功能,并随时监听操作。

               核心代码

                       此处代码主要是完成录像画面的预览,其中会进行USB设备的热插拔监听,拍照Camera属性设置已经Camera对象的初始化,打开预览等操作。

		public void surfaceCreate() throws RemoteException { 
			Log.e(TAG, "surfaceCreate");
			mSurfaceHolder = application.getSurfaceHolder();
			handler.removeCallbacks(USBtask);
			handler.postDelayed(USBtask, 5000);
			try {
				if(!screen_on){
					screen_on = true;
					handler.sendEmptyMessage(GPS_INTERVAL);
					handler.sendEmptyMessageDelayed(RESUME, 3000);
					return;
				}


 

				if(mCamera == null){
					mCamera = Camera.open(cameraId);
					cameraPictureParamsSet();
					mCamera.setPreviewDisplay(mSurfaceHolder);
					startPreview();
					Log.e(TAG, "surfaceCreate mCamera is null, startPreview!");
					if(isRecording){
						cameraListener.autoStartRecord();
						startRecord();
					}
				}else{
  
					if(isRecording)
						cameraListener.autoStartRecord();
					mCamera.setPreviewDisplay(mSurfaceHolder);
					startPreview();
					Log.e(TAG, "surfaceCreate mCamera is not null, startPreview!");
				}
			} catch (IOException e) {
				e.printStackTrace();
			}catch(RuntimeException e){
				cameraListener.noCamera();
			}
		}

                 

            这部分代码就是录像的主要代码了,其中主要涉及到了MediaRecorder的部分操作,包括它输出视频流保存的格式和压缩方式,码率和码流,分辨率等参数的设置。因此处较易出现异常因此建议多catch异常以免程序崩溃。

	private void recordstart(boolean tts){
		hour = 0;
		minute = 0;
		second = 0;
		if (mMediaRecorder == null){
			mMediaRecorder = new MediaRecorder();
		}else{
       	 	mMediaRecorder.reset();
       	 	try {
				mCamera.reconnect();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
        }
		cameraPictureParamsSet();
		mCamera.unlock();
		if(mSurfaceHolder == null)
			mCamera.stopPreview();
        mMediaRecorder.setCamera(mCamera);
        boolean record_toggle = preference.getBoolean("record", true);
        if(record_toggle){
        	mMediaRecorder
            .setAudioSource(MediaRecorder.AudioSource.MIC);
        }
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mMediaRecorder.setVideoFrameRate(mVideoFrameRate);
        mMediaRecorder.setVideoSize(1280, 720);
        mMediaRecorder.setVideoEncodingBitRate(4000000);
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        if(record_toggle){
        	mMediaRecorder
             .setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        	mMediaRecorder.setAudioChannels(1);
        	mMediaRecorder.setAudioSamplingRate(8000);
        }
       mMediaRecorder.setMaxDuration(max_duration_ms);
       mMediaRecorder.setOnErrorListener(CameraService.this);
       mMediaRecorder.setOnInfoListener(CameraService.this);
       getVideoName();
       if(isPathValid){
           try {
  
           	recordingPath = getVideoName().getAbsolutePath();
           	mMediaRecorder.setOutputFile(recordingPath);
           	fileUtils.setRecordingfile(recordingPath);
               mMediaRecorder.prepare();
               mMediaRecorder.start();
               handler.removeCallbacks(task);
               if(isPathValid){
          			handler.postDelayed(task, 1000);
               }
               cameraListener.autoStartRecord();
               if(tts)
               	tts(getString(R.string.isrecodering));
               isRecording = true;
           } catch (IllegalStateException e) {
              
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值