編輯:關於Android編程
獲取圖像
一旦你建立了預覽類和顯示預覽類的viewlayout,你就已准備好開始使用你的應用獲取圖像了.在你的應用代碼中,你還必須要建立起那些用於控制的控件們的偵聽器,來響應用戶的動作.
要取得圖像,使用Camera.takePicture()方法.此方法有三個參數.要獲得JPEG圖像,你必須實現一個Camera.PictureCallback接口來接收圖像數據然後寫入文件中.下面的代碼演示了最基本的Camera.PictureCallback接口的實現.
[java]
private PictureCallback mPicture = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: " +
e.getMessage());
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
private PictureCallback mPicture = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: " +
e.getMessage());
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
通過調用Camera.takePicture()方法觸發圖像獲取事件.下面的代碼演示了如了在一個按鈕的View.OnClickListener方法中調用此方法.
[java]
// 為獲取按鈕增加一個listener
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
// 從相機獲取圖像
mCamera.takePicture(null, null, mPicture);
}
}
);
// 為獲取按鈕增加一個listener
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
// 從相機獲取圖像
mCamera.takePicture(null, null, mPicture);
}
}
);
注:mPicture成員引用自"使用相機"一節的同名成員變量.
注意:記注在用完時要使用Camera.release()來釋放相機對象!關於如何釋放相機,見"釋放相機"一節.
獲取視頻
下面這些配置給MediaRecorder的視頻錄制參數被置為默認值.然而,你可以自己設置這些配置項的值:
setVideoEncodingBitRate()
setVideoSize()
setVideoFrameRate()
setAudioEncodingBitRate()
setAudioChannels()
setAudioSamplingRate()
使用android框架獲取視頻需要小心管理相機對象並且與MediaRecorder類做好協調.當使用相機進行錄像時,你必須管理好Camera.lock()和Camera.unlock()兩個調用以允許MediaRecorder操作相機.
注:從Android4.0 (API level 14)開始,Camera.lock()和Camera.unlock()調用會自動管理.
與從像機獲取圖像不一樣,獲取視頻需要一個十挑剔的調用順序.你必須按照特殊的順序才能成功的准備並獲取視頻,如下所示:
打開相機 –使用Camera.open()來獲取一個相機對象的實例.
連接預覽 -通過Camera.setPreviewDisplay()連接一個SurfaceView到相機來准備一個實時預覽.
開始預覽 –調用Camera.startPreview()來顯示實時圖像.
開始錄制視頻 –下面的步驟必須完整的執行才能成功的錄制視頻:
Unlock相機– 調用Camera.unlock()來Unlock相機以供MediaRecorder使用.
配置MediaRecorder– 按以下順序調用MediaRecorder的方法.更多知識請參考MediaRecorder參考文檔.
setCamera()- 設置視頻獲取所使用的相機,使用你的應用的當前的相機實例.
setAudioSource()- 設置音頻source,使用MediaRecorder.AudioSource.CAMCORDER.
setVideoSource()- 設置視頻source,使用MediaRecorder.VideoSource.CAMERA.
設置視頻輸出的格式和編碼.對於Android2.2 (API Level8)及更高版本,使用MediaRecorder.setProfile方法,使用CamcorderProfile.get()來獲得一個profile.對於之前的版本,你必須用參數來設置視頻輸出格式和編碼:
setOutputFormat()- 設置輸出格式,指定為默認的或MediaRecorder.OutputFormat.MPEG_4.
setAudioEncoder()- 設置音頻編碼類型,指定為默認的或MediaRecorder.AudioEncoder.AMR_NB.
setVideoEncoder()- 設置視頻編碼類型,指定為默認的或MediaRecorder.VideoEncoder.MPEG_4_SP.
setOutputFile()-指定輸出文件,使用getOutputMediaFile(MEDIA_TYPE_VIDEO).toString(),這個方法是"保存媒體文件"一節(在後面)中的例子代碼.
setPreviewDisplay()- 為你的應用指定SurfaceView預覽layout元素,使用在連接預覽時指定的相同對象.
注意:你必須按上面的順序調用MediaRecorder的配置方法們,否則你的應用將遇到悲劇從而失敗.
准備MediaRecorder- 准備MediaRecorder,主要是通過調用配置方法MediaRecorder.prepare().
開始MediaRecorder- 調用MediaRecorder.start()開始錄制視頻.
停止錄制視頻 –依次調用下面的方法,才能成功結束一個視頻錄制過程:
停止MediaRecorder– 調用MediaRecorder.stop()停止錄制視頻.
重置MediaRecorder– 可選的,調用MediaRecorder.reset()可以將以前的配置取消.
釋放MediaRecorder– 調用MediaRecorder.release()來釋放MediaRecorder.
鎖住相機 -調用Camera.lock()鎖住相機以使後面的MediaRecorder會話也可以使用相機.從Android4.0 (API level 14)開始,此調用僅在MediaRecorder.prepare()調用失敗時才需要.
停止預覽 –當你的activity完成了對相機的使用,使用Camera.stopPreview()停止預覽.
釋放相機- 調用Camera.release()釋放相機,以使其它應用也可使用它.
注:不創建相機預覽並且略過前幾步也是可以使用MediaRecorder.然而,用戶一般還是想看預覽的,所以此處不討論這種情況.
技巧:如果你的應用是專為錄像寫的,那麼在啟動你的預覽之前調用setRecordingHint(boolean)並傳入true,這樣可以幫你減少啟動錄制的時間.
配置MediaRecorder
當使用MediaRecorder類來錄制視頻,你必須按特定步驟執行配置過程,然後調用MediaRecorder.prepare()方法來檢查並實現所給予的配置.下面的例子代碼演示了如何為視頻錄制正確的配置並准備MediaRecorder類.
[java]
private boolean prepareVideoRecorder(){
mCamera = getCameraInstance();
mMediaRecorder = new MediaRecorder();
// Step 1: 解鎖相機並設置給MediaRecorder
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
// Step 2: 設置sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: 設置一個CamcorderProfile (在API Level 8或更高版本中)
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
// Step 4: 設置輸出文件
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
// Step 5: 設置預覽輸出
mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
// Step 6: 准備配置MediaRecorder
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
} catch (IOException e) {
Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
return true;
}
private boolean prepareVideoRecorder(){
mCamera = getCameraInstance();
mMediaRecorder = new MediaRecorder();
// Step 1: 解鎖相機並設置給MediaRecorder
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
// Step 2: 設置sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: 設置一個CamcorderProfile (在API Level 8或更高版本中)
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
// Step 4: 設置輸出文件
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
// Step 5: 設置預覽輸出
mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
// Step 6: 准備配置MediaRecorder
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
} catch (IOException e) {
Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
return true;
}
在Android2.2 (API Level8)之前,你必須直接設置輸出格式和編碼格式等參數,而不是使用CamcorderProfile.可以像下面這樣做:
[java]
// Step 3: 設置輸出格式和編碼(for versions prior to API Level 8)
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
// Step 3: 設置輸出格式和編碼(for versions prior to API Level 8)
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
下面這些配置給MediaRecorder 的視頻錄制參數被置為默認值.然而,你可以自己設置這些配置項的值:
· setVideoEncodingBitRate()
· setVideoSize()
· setVideoFrameRate()
· setAudioEncodingBitRate()
· setAudioChannels()
· setAudioSamplingRate()
開始和停止MediaRecorder
當使用MediaRecorder開始和停止錄像時,你必須按特定的順序進行調用,如下所列:
· 使用Camera.unlock()解鎖相機
· 按上面代碼所演示的配置MediaRecorder
· MediaRecorder.start()開始錄像
· 錄制視頻
· 使用MediaRecorder.stop()停止錄像
· 用MediaRecorder.release()釋放MediaRecorder
· 用Camera.lock()鎖住相機 www.2cto.com
下面的示例代碼演示如何通過一個按鈕來使用相機和MediaRecorder類正確的開始和停止視頻錄制
注:當完成一個視頻錄制,不要釋放相機,否則你的預覽將被迫停止.
[java]
private boolean isRecording = false;
// 向錄像按鈕增加監聽器
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isRecording) {
// 停止錄像並釋放 MediaRecorder
mMediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); // take camera access back from MediaRecorder
// inform the user that recording has stopped
setCaptureButtonText("Capture");
isRecording = false;
} else {
// 初始化視頻相機
if (prepareVideoRecorder()) {
// 相幾解鎖,MediaRecorder 已准備好.現在可以開始錄像了
mMediaRecorder.start();
// inform the user that recording has started
setCaptureButtonText("Stop");
isRecording = true;
} else {
// 准備過程失敗,釋放相機
releaseMediaRecorder();
// inform user
}
}
}
}
);
private boolean isRecording = false;
// 向錄像按鈕增加監聽器
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isRecording) {
// 停止錄像並釋放 MediaRecorder
mMediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); // take camera access back from MediaRecorder
// inform the user that recording has stopped
setCaptureButtonText("Capture");
isRecording = false;
} else {
// 初始化視頻相機
if (prepareVideoRecorder()) {
// 相幾解鎖,MediaRecorder 已准備好.現在可以開始錄像了
mMediaRecorder.start();
// inform the user that recording has started
setCaptureButtonText("Stop");
isRecording = true;
} else {
// 准備過程失敗,釋放相機
releaseMediaRecorder();
// inform user
}
}
}
}
);
注:在上例中,prepareVideoRecorder()方法引用自例子"配置MediaRecorder".此方法解鎖相機配置並准備MediaRecorder實例.
作者:nkmnkm
前言android中有很多現成的組件可以使用,但是android上面的程序很多時候用系統自帶的組件都不太合適,主要是樣式可能不是我們想要的。這個時候我們就需要定制一些樣式
上篇博客已經實現了地圖的定位以及結合了方向傳感器用戶路癡定位方向,如果你還不清楚,請查看:Android 百度地圖 SDK v3.0.0 (二) 定位與結合
最近在做Android應用的混淆,踩了一些坑,這裡記錄分享下個人的心得。混淆介紹首先先簡單說一下什麼是混淆和混淆的作用,其實這個搜索下可以找到一堆官方的說法等等,這裡簡單
Android記錄17-sdk更新、Eclipse下查看源碼、chm文檔提供等干貨 本篇博客分享一些Android開發者提高開發效率的一些干貨,之從Google被和諧了之