編輯:關於Android編程
把預覽類放到布局中
Camera的預覽類,如上文所示的示例,必須要跟用戶界面控件一起放到一個Activity的布局中,以便拍照或錄像。本段向你顯示如果構建一個基本的用於預覽的Activity布局。
下面的布局代碼提供了一個很基本的View,它能夠用於顯示Camera的預覽圖像。在這個示例中,FrameLayout元素被用於Camera預覽類的容器。使用這個布局類型可以讓額外的圖像信息或控件能夠覆蓋在實時的Camera預覽圖像之上。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<FrameLayout
android:id="@+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
/>
<Button
android:id="@+id/button_capture"
android:text="Capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>
在大多數設備上,Camera預覽的默認方向是橫向。這個示例布局指定了一個水平(橫向)布局,並且下面的代碼把應用程序固定為橫向。為了簡化Camera預覽中的展現,你應該通過在你的清單文件中添加以下設置,把應用程序的預覽Activity的方向改變為橫向的:
<activity android:name=".CameraActivity"
android:label="@string/app_name"
android:screenOrientation="landscape">
<!-- configure this activity to use landscape orientation -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
注意:Camera的預覽不一定就是橫屏模式。從Android2.2(API Level8)開始,你能夠使用setDisplayOrientation()方法來設置預覽圖像的旋轉。為了重新定位用戶手的預覽方向,在你的預覽類的surfaceChanged()方法中,首先要用Camera.stopPreview()方法停止預覽,然後改變方向,再用Camera.startPreview()方法啟動預覽。
在Camera View的Activity中,把你的預覽類添加到上例所示的FrameLayout元素中。你的Camera Activity還必須確保在它被掛起或關閉時,要釋放Camera對象。以下示例顯示如何把上文中創建的預覽類添加到Camera的Activity中:
public class CameraActivity extends Activity {
private Camera mCamera;
private CameraPreview mPreview;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
}
}
注意:上例中的getCameraInstance()方法引用了上文“訪問Camera”中的示例方法。
采集圖片
一旦你構建了一個預覽類,並把它放到了一個View中,你就可以開始用你的應用程序來采集應用程序了。在你的應用程序代碼中,必須建立用於響應用戶拍照操作的用戶界面控件的監聽器。
要使用Camera.takePicture()方法來獲取一張圖片。這個方法需要3個參數來接收來自Camera的數據。為了接收JPEG格式的數據,你必須實現接收圖片數據的Camera.PictureCallback接口,並把接收到數據寫到一個文件中。下面的代碼顯示了一個Camera.PictureCallback接口的基本實現,它把從Camera接收到的數據保存到一個圖片文件中:
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中調用這個方法:
// Add a listener to the Capture button
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);
注意:代碼中的mPicture成員變量會在下面的示例代碼中引用。
警告:記住,在應用程序使用完Camera對象後,一定要調用Camera.release()方法來釋放Camera對象。
采集視頻
使用Android框架采集視頻需要認真的管理Camera對象,以及跟MediaRecorder類的協調。當使用Camera對象記錄視頻時,除了Camera.open()和Camera.release()方法的調用以外,還必須管理Camera.lock()和Camera.unlock()方法的調用,從而允許MediaRecorder對象訪問Camera硬件。
注意:從Android4.0(API Level 14)開始,Camera.lock()和Camera.unlock()方法調用系統會為你自動管理。
跟拍照不一樣,采集視頻需要非常特殊的調用順序,必須按照一個特定執行順序來准備和采集視頻,詳細如下:
1. 打開Camera:使用Camera.open()方法來獲得一個Camera對象的實例。
2. 連接預覽:使用Camera.setPreviewDisplay()方法把SurfaceView跟Camera連接起來,准備一個實時的Camera圖像預覽界面。
3. 啟動預覽:調用Camera.starPreview()方法開始顯示實時的Camera圖像。
4. 啟動視頻錄像:為了成功的記錄視頻,必須完成以下步驟。
a. 給Camera對象解鎖:通過調用Camera.unlock()方法給由MediaRecorder對象使用的Camera對象解鎖。
b. 配置MediaRecorder對象:在這一步中要調用以下MediaRecorder方法。更多信息,請看MediaRecorder參考文檔。
1. setCamera():使用應用程序當前的Camera實例,把它設置成用於視頻采集;
2. setAudiioSource():使用MediaRecorder.AudioSource.CAMCORDER,設置音頻源;
3. setVideoSource():使用MediaRecorder.VideoSource.CAMERA來設置視頻源;
4. 設置視頻的輸出格式和編碼。對於Android2.2以上的版本,要使用MediaRecorder.setProfile方法,並且要私用CamcorderProfile.get()方法來獲得一個Profile的示例。對於Android2.2以前的版本,必須要設置視頻輸出的格式和編碼參數:
I. setOutputFormat():設置輸出格式,指定默認設置,或者是MediaRecorder.OutputFormat.MPEG_4;
II. setAudioEncoder():設置聲音的編碼類型,指定默認設置,或者是MediaRecorder.AudioEncoder.AMR_NB;
III.setVideoEncoder():設置視頻的編碼類型,指定默認設置,或者是MediaRecorder.VideoEncoder.MPEG_4_SP;
5. setOutputFile():設置輸出文件,可以使用下文“保存媒體文件”中的示例代碼中的getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()方法來獲取輸出文件路徑。
6. setPreviewDisplay():給應用程序指定SurfaceView的預覽布局。要使用與連接預覽相同的對象。
警告:這步中必須要調用MediaRecorder的配置方法,否則你的應用程序將會發生錯誤,並且錄像也會失敗。
c. 准備MediaRecorder對象:通過調用MediaRecorder.prepare()方法,准備給MediaRecorder對象提供的配置設置。
d. 啟動MediaRecorder對象:通過調用MediaRecorder.star()方法來記錄視頻。
5. 停止視頻錄像:在這步中要調用以下方法來成功完成視頻記錄:
a. 停止MediaRecorder對象:通過調用MediaRecorder.stop()方法來停止視頻采集
b. 重置MediaRecorder對象:可選操作,通過調用MediaRecorder.reset()方法來刪除記錄器的配置設置。
c. 釋放MediaRecorder對象:調用MediaRecorder.release()方法來釋放MediaRecorder對象。
d. 鎖定Camera對象:調用Camera.lock()方法來鎖定Camera對象,以便MediaRecorder會話能夠繼續使用它。從Android4.0(API Level 14)開始,這個調用不再需要了,除非MediaRecorder.prepare()方法調用失敗。
6. 停止預覽:當Activity使用完Camera對象時,要使用Camera.stopPreview()方法來停止預覽。
7. 釋放Camera對象:調用Camera.release()方法來釋放Camera對象,以便其他應用程序能夠使用它。
注意:使用MediaRecorder對象,不首先創建Camera預覽,並跳過這個過程開始的幾步是可能的。但是,因為典型的在開始視頻采集之前,要給用戶看到圖像預覽,所以跳過的步驟It is possible to use MediaRecorder without creating a camera preview first and skip the first few steps of this process.在此就不討論了。
提示:如果你的應用程序被用於典型的視頻記錄,那麼在啟動預覽期間,把setRecordingHint(boolean)方法設置為true,這樣有助於減少啟動采集所需要的時間。
配置MediaRecorder對象
在使用MediaRecorder類來采集視頻時,必須按照指定的順利來執行配置處理,並且要調用MediaRecorder.prepare()方法來檢查和實現配置。下面的示例代碼演示了如何為采集視頻配置和准備MediaRecorder類:
private boolean prepareVideoRecorder(){
mCamera = getCameraInstance();
mMediaRecorder = new MediaRecorder();
// Step 1: Unlock and set camera to MediaRecorder
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
// Step 2: Set sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
// Step 4: Set output file
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
// Step 5: Set the preview output
mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
// Step 6: Prepare configured 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類。下面的代碼演示了這種方法:
// Step 3: Set output format and encoding (for versions prior to API Level 8)
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
以下是給MediaRecorder對象設置的默認的視頻采集參數,但是你可以在你的應用程序中來調整這些設置:
1. setVideoEncodingBitRate()
2. setVideoSize()
3. setVideoFrameRate()
4. setAudioEncodingBitRate()
5. setAudioChannels()
6. setAudioSamplingRate()
啟動和停止MediaRecorder對象
在使用MediaRecorder類來啟動和停止視頻采集時,必須按照以下順序來執行:
1. 用Camera.unlock()方法來解鎖Camera對象;
2. 向上面代碼中顯示的那樣來配置MediaRecorder;
3. 使用MediaRecorder.start()方法來啟動采集;
4. 記錄視頻;
5. 使用MediaRecorder.stop()方法來停止采集;
6. 使用MediaRecorder.release()方法來釋放媒體記錄器;
7. 使用Camera.lock()方法來鎖定Camera對象。
以下示例代碼演示了如何觸發一個按鈕正確的使用Camera和MediaRecorder類來啟動和停止視頻采集。
注意:當完成視頻采集時,不要釋放Camera,否則你的預覽將會被停止。
private boolean isRecording = false;
// Add a listener to the Capture button
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isRecording) {
// stop recording and release camera
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 {
// initialize video camera
if (prepareVideoRecorder()) {
// Camera is available and unlocked, MediaRecorder is prepared,
// now you can start recording
mMediaRecorder.start();
// inform the user that recording has started
setCaptureButtonText("Stop");
isRecording = true;
} else {
// prepare didn't work, release the camera
releaseMediaRecorder();
// inform user
}
}
}
}
);
注意:在上面的例子中,prepareVideoRecorder()方法引用了“配置MediaRecorder”一節中的示例代碼。這個方法要鎖定Camera,然後配置和准備MediaRecorder示例。
釋放Camera
Camera是一種由應用程序共享的設備資源。在獲得一個Camera實例之後,你的應用程序才能夠使用Camera,並且要特別小心,在應用程序停止使用它的時候,即使是是應用程序被掛起(Activity.onPause()),一定要釋放Camera對象。如果應用程序沒有正確的釋放Camera,所有後續的訪問Camera的嘗試,包括你自己的應用程序,都會因訪問失敗而導致應用程序被關閉。
像下面的示例代碼那樣,使用Camera.release()方法來釋放Camera對象:
public class CameraActivity extends Activity {
private Camera mCamera;
private SurfaceView mPreview;
private MediaRecorder mMediaRecorder;
...
@Override
protected void onPause() {
super.onPause();
releaseMediaRecorder(); // if you are using MediaRecorder, release it first
releaseCamera(); // release the camera immediately on pause event
}
private void releaseMediaRecorder(){
if (mMediaRecorder != null) {
mMediaRecorder.reset(); // clear recorder configuration
mMediaRecorder.release(); // release the recorder object
mMediaRecorder = null;
mCamera.lock(); // lock camera for later use
}
}
private void releaseCamera(){
if (mCamera != null){
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
Android 啟動模式: 啟動模式:LaunchMode在多個Activity跳轉的過程中扮演著重要的角色,它可以決定是否
本文實例講述了Android編程中HTTP服務用法。分享給大家供大家參考,具體如下:在Android中,除了使用java.net包下的API訪問HTTP服務之外,我們還可
一、Canvas Canvas中的方法很多,這裡我們只挑常用的進行講解說明 Canvas可以繪制的對象有: 弧線(arcs) canvas. 填充顏色(argb和co
首先,定義一個服務,在這個服務裡面,完成土司的創建(小火箭布局創建)煙的效果屬於動畫播放,而且要依托一個activity。(這個activity要定義為透明狀態)定義煙的
實現功能:實現NetMusicListAdapter(網絡音樂列表適配器