文章出處: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檔案下