android源碼解析 ---- camera 照相機 攝像機 .

 

文章出處:http://blog.csdn.net/dany1202/archive/2011/01/26/6164450.aspx

 

一.camera啓動
1.一個activity啓動調用流程:
    onCreate()-->onStart()-->onResume()
    onCreate():
    1.可添加所需佈局文件,畫界面。
    2.開啓線程,啓動硬件攝像頭,調用CameraHolder.instance().open()得到一個android.hardwareCamera實例mCameraDevice
        ensureCameraDevice()-->CameraHolder.instance().open()-->mCameraDevice.getParameters();確保攝像頭存在,並將攝像頭打開。
        startPreview();開始取景預覽
    3.創建 VideoPreview 的SurfaceHolder,同時註冊callback函數,當VideoPreview的長寬變化時,調用SurfaceChanged()函數
        mSurfaceView = (SurfaceView) findViewById(R.id.camera_preview);
            SurfaceHolder holder = mSurfaceView.getHolder();
            holder.addCallback(this);
            holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    4.mIsImageCaptureIntent是否爲從短信息或聯繫人編輯界面發送的intent到camera
        mIsImageCaptureIntent = isImageCaptureIntent();當該函數返回true時,表示從短信息或聯繫人界面跳轉到拍照界面;
        爲false時,表示從桌面程序正常啓動camera;要注意兩種不同情況所需的右側界面功能按鈕區有變動。
    onStart():
    1.mSwitcher.setSwitch(SWITCH_CAMERA)設置拍照錄像切換按鈕切換到照相模式。
    onResume()
    startPreview()重新開始預覽
    1.當按home鍵退出程序時,會掉用stopPreview(),故再次進入時,會執行onResume()函數,在此函數中,應重新開啓預覽功能。
    2.keepScreenOnAwhile()點亮屏幕,防止屏幕變黑。

2.拍照錄像切換功能
    1.Switcher繼承自ImageView,在佈局文件中直接佈局即可
    2.mSwitch爲true時,滑塊在下方,顯示拍照界面;當mSwitch爲false時,滑塊在上方,顯示錄像界面。
    3.當點擊或觸碰拍照錄像切換按鈕時:
        MotionEvent.ACTION_UP-->tryToSetSwitch()-->mListener.onSwitchChanged(this, onOff)
        在camera.java中實現該接口,調用switchToVideoMode()-->MenuHelper.gotoVideoMode(this)-->startCameraActivity(),並結束當前程序。

3.updateThumbnailButton()更新功能按鈕去的到相簿按鈕
    1.調用事件:
        initializeFirstTime初始化時調用
        initializeSecondTime()時調用
        Intent.ACTION_MEDIA_SCANNER_FINISHED,掃描SD卡結束時調用
    2.mThumbController.isUriValid(),當圖庫裏有圖片時,值爲TRUE;當圖庫裏無圖片時,值爲FALSE。
    3.updateLastImage()更新到相簿按鈕上的顯示圖片。
    4.mThumbController.updateDisplayIfNeeded()-->if (mUri == null) mButton.setImageDrawable(null);當圖庫無照片時,此處不顯示任何照片。

4.shutterButton拍照按鈕
    1.對焦調用流程
    按下屏幕上的ShutterButton 按鈕。
    ShutterButton.java中的監聽線程 調用callShutterButtonFocus(),這個函數會調用接口ShutterButton.OnShutterButtonListener 的函數onShutterButtonFocus()。
       Camera.java實現了接口ShutterButton.OnShutterButtonListener。故Camera.java中的函數onShutterButtonFocus()被調用。
    接着的執行流程爲-----> doFocus()------>autoFocus()--->mCameraDevice.autoFocus()
    2.拍照調用流程
    之後ShutterButton.java調用performClick(),這個函數中調用了Camera.java中的onShutterButtonClick()
    接着的執行流程爲 ----->dosnap()----->ImagePicture.onSnap()----->ImageCapture.initiate()---->ImageCapture.capture() 此函數執行完後,takepicture 過程完成
    takePicture 完成後,surfaceChanged()將被調用將剛照下的照片顯示在屏幕上。
    Camera.java中的回調接口JpegPictureCallback中的函數onPictureTaken()接着執行。這個函數先調用ImageCapture.storeImage()將jpeg圖像數據存儲在內存。
    3.picture 的thumbnail顯示過程:
    ImageCapture.storeImage()--->ImageCapture.setLastPictureThumb()---> mThumbController.setData(uri, lastPictureThumb);

 

5.佈局文件

    1.attach_camera_control.xml,當從短信息或聯繫人界面,進入camera時,右側功能按鈕區的“確定” “重拍”及“取消”

    2.camera_control.xml,camera和videocamera主界面右側的功能按鈕區的佈局

    3.camera.xml,camera主界面左側預覽取景區的佈局

    4.video_camera.xml,videocamera主界面左側預覽取景區的佈局

    5.on_screen_hint.xml,SD卡相關信息的輸出,如在屏幕下方提示“使用相機前請先插入 SD 卡。”

 

6.照相機SD卡

    1.BroadcastReceiver mReceiver,接受SD卡發出的狀態變化消息。

    2.Intent.ACTION_MEDIA_MOUNTED 掛在

       Intent.ACTION_MEDIA_UNMOUNTED 未掛在

       Intent.ACTION_MEDIA_CHECKING SD卡從未插入到插入的過程中會調用此狀態

       Intent.ACTION_MEDIA_SCANNER_FINISHED 掃描SD卡結束,即SD卡進入可使用狀態

    3.checkStorage()->calculatePicturesRemaining()->MenuHelper.calculatePicturesRemaining()計算SD卡剩餘空間

    4.updateStorageHint()更新界面提示顯示文字

       其中MenuHelper.NO_STORAGE_ERROR包含SD卡狀態:MEDIA_CHECKING,MEDIA_SHARED,等SD卡被移除狀態

       state = Environment.getExternalStorageState()獲取SD卡狀態

             如state.equals(Environment.MEDIA_CHECKING)表示SD卡正在準備中

       mStorageHint = OnScreenHint.makeText(this, noStorageText);設置當前界面需顯示的內容

       mStorageHint.show();顯示SD卡狀態文字

 

7. 攝像機SD卡,比照相機稍微麻煩一些

    1.onResume()函數中註冊receive事件

       IntentFilter intentFilter =
                new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
        intentFilter.addAction(Intent.ACTION_MEDIA_EJECT);
        intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
        intentFilter.addDataScheme("file");
        mReceiver = new MyBroadcastReceiver();
        registerReceiver(mReceiver, intentFilter);
        mStorageStatus = getStorageStatus(true);

    2.class MyBroadcastReceiver處理接收到的如上註冊事件

        比如其中

          if (action.equals(Intent.ACTION_MEDIA_EJECT)) {
                updateAndShowStorageHint(false);
                stopVideoRecording();
         }在當拔出SD卡是觸發

     3.updateAndShowStorageHint()->getStorageStatus()

         此處 當remaining == NO_STORAGE_ERROR,可添加如SHARE,CHECKING等狀態的處理

         根據不同的狀態,返回不同的值

         例如:

             if (state.equals(Environment.MEDIA_CHECKING)) {              
                return STORAGE_STATUS_PREPARE;
            }else if(state.equals(Environment.MEDIA_SHARED)){              
                return STORAGE_STATUS_SHARE;
            }else {                     
                return STORAGE_STATUS_NONE;
            }

          當然,所填家的事件需要在1.2步驟中進行註冊並調用此函數

      4.showStorageHint()

         在switch (mStorageStatus)處理所需顯示信息

         例如,添加如下case語句,處理如上添加的SHARE狀態

         case STORAGE_STATUS_SHARE:
                errorMessage = getString(R.string.sdcard_busy_message);
                break;

      5.mStorageHint = OnScreenHint.makeText(this, errorMessage);設置所需顯示文字內容

      6.mStorageHint.show();顯示在當前攝像機界面中

 

8.取景預覽去右側設置條

    1.在oncreat()或者xml文件中,我們找不到設置項對應的佈局,那麼設置項是在什麼地方添加的呢?

       changeHeadUpDisplayState()該函數即位添加此佈局的入口。

    2.res/xml/camera_preferences.xml

      其相應的圖片及文字值位於該xml文件下

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章