protected void getImageFromAlbum() { Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*");//相片類型
Camera.java
經過源碼能夠發現,輸出的圖片有2個分支
若是你沒有指定Intent裏面的Extra參數,它就返回一個序列化(putExtra("data", bitmap))的Bitmap,從理論上來講,這樣的代碼寫的很爛,屬於Magic Number。
若是你指定了Intent裏面的Extra參數MediaStore.EXTRA_OUTPUT,拍照後它就直接把bitmap寫到了Uri裏面了,返回是空
使用範圍:得到很小的預覽圖,用於設置頭像等地方。
返回示例:bitmap = data.getExtras().getParcelable("data");java
public final static int REQUEST_IMAGE_CAPTURE = 1; //start Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, REQUEST_IMAGE_CAPTURE); //receive @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode != RESULT_OK) { Log.d(TAG, "canceled or other exception!"); return; } if (requestCode == REQUEST_IMAGE_CAPTURE) { Log.d(TAG, "REQUEST_IMAGE_CAPTURE"); Bitmap bitmap; try { bitmap = data.getExtras().getParcelable("data"); //TODO:do something with bitmap, Do NOT forget call Bitmap.recycler(); mCameraImageview.setImageBitmap(bitmap); } catch (ClassCastException e){ //do something with exceptions e.printStackTrace(); } } }
得到原始的拍照文件
使用範圍:用於處理大的圖片,好比使用濾鏡,上傳原始圖像等操做,注意Uri不要用data私有目錄,不然相機是寫不進去的。android
public final static int REQUEST_IMAGE_CAPTURE = 1; Uri outputFileUri; //start @OnClick(R.id.itemSelectCamera) void itemSelectCamera() { File file = FileUtils.createImageFile(); outputFileUri = Uri.fromFile(file); Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); startActivityForResult(captureIntent, REQUEST_IMAGE_CAPTURE); } //receive @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode != RESULT_OK) { Log.d(TAG, "canceled or other exception!"); return; } if (requestCode == REQUEST_IMAGE_CAPTURE) { Log.d(TAG, "REQUEST_IMAGE_CAPTURE"); //TODO:Use the Uri Intent intent = new Intent(this, ImageFilterActivity.class); intent.setData(outputFileUri); startActivity(intent); } }
關於文件如何建立,目前我找到的就是這個最穩定了,寫到SD卡根目錄,data目錄(Context.getXXDir())是私有目錄,其它程序(好比Camera)是寫不進去的app
public class FileUtils { public static File createImageFile() { // Create an image file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; try { File image = File.createTempFile(imageFileName, /* prefix */ ".jpg", /* suffix */ Environment.getExternalStorageDirectory() /* directory */); return image; } catch (IOException e) { //do noting return null; } } }
第一步:在Eclipse中建立一個名爲AndroidCamera的Android工程,可參見Helloworld的例子;
第二步:在AndroidManifest.xml中添加使用Camera相關的聲明以下:ide
<uses-feature android:name="android.hardware.camera" android:required="false" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
第三步:編寫AndroidCameraActivity類,以下:函數
import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.widget.Toast; public class AndroidCameraActivity extends Activity { private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200; private Intent intent = null; private Uri fileUri = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);//create a intent to record video fileUri = getOutputMediaFileUri(); // create a file Uri to save the video // set the video file name intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the video quality high intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // start the video capture Intent startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) { if (resultCode == RESULT_OK) { // video captured and saved to fileUri specified in the Intent Toast.makeText(this, "Video saved to:\n" + data.getData(), Toast.LENGTH_LONG).show(); } else if (resultCode == RESULT_CANCELED) { // User cancelled the video capture } } } /** Create a File Uri for saving a video */ private static Uri getOutputMediaFileUri(){ //get the mobile Pictures directory File picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); //get the current time String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); File videoFile = new File(picDir.getPath() + File.separator + "VIDEO_"+ timeStamp + ".mp4"); return Uri.fromFile(videoFile); } }
MediaRecorder類詳解
手機通常都有麥克風和攝像頭,而Android系統就能夠利用這些硬件來錄製音視頻了。
爲了增長對錄製音視頻的支持,Android系統提供了一個MediaRecorder的類。
結構:ui
Java.lang.Object android.media.MediaRecorder
與MediaPlayer類很是類似MediaRecorder也有它本身的狀態圖。下面是關於MediaRecorder的各個狀態的介紹:
Initial:初始狀態,當使用new()方法建立一個MediaRecorder對象或者調用了reset()方法時,該MediaRecorder對象處於Initial狀態。在設定視頻源或者音頻源以後將轉換爲Initialized狀態。另外,在除Released狀態外的其它狀態經過調用reset()方法均可以使MediaRecorder進入該狀態。
Initialized:已初始化狀態,能夠經過在Initial狀態調用setAudioSource()或setVideoSource()方法進入該狀態。在這個狀態能夠經過setOutputFormat()方法設置輸出格式,此時MediaRecorder轉換爲DataSourceConfigured狀態。另外,經過reset()方法進入Initial狀態。
DataSourceConfigured:數據源配置狀態,這期間能夠設定編碼方式、輸出文件、屏幕旋轉、預覽顯示等等。能夠在Initialized狀態經過setOutputFormat()方法進入該狀態。另外,能夠經過reset()方法回到Initial狀態,或者經過prepare()方法到達Prepared狀態。
Prepared:就緒狀態,在DataSourceConfigured狀態經過prepare()方法進入該狀態。在這個狀態能夠經過start()進入錄製狀態。另外,能夠經過reset()方法回到Initialized狀態。
Recording:錄製狀態,能夠在Prepared狀態經過調用start()方法進入該狀態。另外,它能夠經過stop()方法或reset()方法回到Initial狀態。
Released:釋放狀態(官方文檔給出的詞叫作Idle state 空閒狀態),能夠經過在Initial狀態調用release()方法來進入這個狀態,這時將會釋放全部和MediaRecorder對象綁定的資源。
Error:錯誤狀態,當錯誤發生的時候進入這個狀態,它能夠經過reset()方法進入Initial狀態。
提示:與MediaPlayer類似使用MediaRecorder錄音錄像時須要嚴格遵照狀態圖說明中的函數調用前後順序,在不一樣的狀態調用不一樣的函數,不然會出現異常。
實例描述了的建立過程this
MediaRecorder recorder=newMediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC); recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); recorder.setOutputFile(PATH_NAME); recorder.prepare(); recorder.start(); // Recording is now started ... recorder.stop(); recorder.reset(); // You can reuse the object by going back to setAudioSource() step recorder.release();// Now the object cannot be reused
實踐
使用MediaRecorder錄製聲音的:
1) 建立 MediaRecorder 對象。
2) 調用MediaRecorder對象的setAudioSource()方法設置聲音來源,通常傳入 MediaRecorder. AudioSource.MIC參數指定錄製來自麥克風的聲音。
3) 調用MediaRecorder對象的setOutputFormat()設置所錄製的音頻文件的格式。
4) 調用MediaRecorder 對象的setAudioEncoder()、setAudioEncodingBitRate(intbitRate)、 setAudioSamplingRate(int samplingRate)設置所錄製的聲音的編碼格式、編碼位率、採樣率等, 這些參數將能夠控制所錄製的聲音的品質、文件的大小。通常來講,聲音品質越好,聲音文件越大。
5) 調用MediaRecorder的setOutputFile(Stringpath)方法設置錄製的音頻文件的保存位置。
6) 調用MediaRecorder的prepare()方法準備錄製。
7) 調用MediaRecorder對象的start()方法開始錄製。
8) 錄製完成,調用MediaRecorder對象的stop()方法中止錄製,並調用release()方法釋放資源。編碼
<span style="font-size:18px;">package com.jph.recordsound; import java.io.File; import org.crazyit.sound.R; import android.app.Activity; import android.media.MediaRecorder; import android.os.Bundle; import android.os.Environment; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageButton; import android.widget.Toast; public class RecordSound extends Activity implements OnClickListener { // 定義界面上的兩個按鈕 ImageButton record, stop; // 系統的音頻文件 File soundFile; MediaRecorder mRecorder; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 獲取程序界面中的兩個按鈕 record = (ImageButton) findViewById(R.id.record); stop = (ImageButton) findViewById(R.id.stop); // 爲兩個按鈕的單擊事件綁定監聽器 record.setOnClickListener(this); stop.setOnClickListener(this); } @Override public void onDestroy() { if (soundFile != null && soundFile.exists()) { // 中止錄音 mRecorder.stop(); // 釋放資源 mRecorder.release(); mRecorder = null; } super.onDestroy(); } @Override public void onClick(View source) { switch (source.getId()) { // 單擊錄音按鈕 case R.id.record: if (!Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED)) { Toast.makeText(RecordSound.this, "SD卡不存在,請插入SD卡!", Toast.LENGTH_SHORT).show(); return; } try { // 建立保存錄音的音頻文件 soundFile = new File(Environment .getExternalStorageDirectory().getCanonicalFile() + "/sound.amr"); mRecorder = new MediaRecorder(); // 設置錄音的聲音來源 mRecorder.setAudioSource(MediaRecorder .AudioSource.MIC); // 設置錄製的聲音的輸出格式(必須在設置聲音編碼格式以前設置) mRecorder.setOutputFormat(MediaRecorder .OutputFormat.AMR_NB); // 設置聲音編碼的格式 mRecorder.setAudioEncoder(MediaRecorder .AudioEncoder.AMR_NB); mRecorder.setOutputFile(soundFile.getAbsolutePath()); mRecorder.prepare(); // 開始錄音 mRecorder.start(); //① } catch (Exception e) { e.printStackTrace(); } break; // 單擊中止按鈕 case R.id.stop: if (soundFile != null && soundFile.exists()) { // 中止錄音 mRecorder.stop(); //② // 釋放資源 mRecorder.release(); //③ mRecorder = null; } break; } } }</span>
結果圖
spa