Android之多媒體資料採集
阿新 • • 發佈:2018-12-13
Demo 1錄音機
下面來分析:
各種引用的建立(比較特殊的ImageButton 和 MediaRecorder) 初始化我就不多說 Handler的使用 上篇博文談過不多說 關於這種寫法的監聽可以借鑑(畢竟所有控制元件只不過是View的子類而已) 然後讀取有沒有記憶體卡 Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED) 初始化臨時檔案File.createTempFile( 引數一基本檔名 引數二字尾 引數三目錄路徑)
不多說下面看settime的程式碼 傳送Bundle 不多談
結束錄音的時候 原始碼如下
public class MyAudioRecorderActivity extends Activity implements OnClickListener{ public static final int UPDATE_TIME=0;//更新錄音時間的訊息編號 ImageButton ibRecord;//錄製按鈕 ImageButton ibStop;//停止按鈕 TextView tvTime;//時間長度顯示 Handler hd;//訊息處理器 File myFile ;//用於存放音軌的檔案 MediaRecorder myMediaRecorder;//媒體錄音機 int countSecond=0;//錄製的秒數 boolean recordFlag=false;//錄製中標誌 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //初始化按鈕引用 ibRecord=(ImageButton)findViewById(R.id.ImageButton01); ibStop=(ImageButton)findViewById(R.id.ImageButton02); //初始化顯示錄音時長的文字框 tvTime=(TextView)findViewById(R.id.TextView02); //為錄製按鈕新增監聽器 ibRecord.setOnClickListener(this); //為停止按鈕新增監聽器 ibStop.setOnClickListener(this); //初始化訊息處理器物件 //本案例中希望通過附加執行緒修改TextView中的內容,因此要在主 //執行緒中建立一個Handler hd=new Handler() { @Override public void handleMessage(Message msg) { //呼叫父類處理 super.handleMessage(msg); //根據訊息what編號的不同,執行不同的業務邏輯 switch(msg.what) { //將訊息中的內容提取出來顯示在Toast中 case UPDATE_TIME: //獲取訊息中的資料 Bundle b=msg.getData(); //獲取內容字串 String msgStr=b.getString("msg"); //設定字串到顯示錄音時長的文字框中 tvTime.setText(msgStr); break; } } }; } @Override public void onClick(View v) { if(v == ibRecord){//按下錄音按鈕 if(!Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {//若沒有插快閃記憶體卡則報錯 Toast.makeText(this, "請檢測記憶體卡", Toast.LENGTH_SHORT).show(); return; } try { if(recordFlag==true) {//若已經在錄音中則提示並返回 Toast.makeText(this, "錄音中,請結束本次錄音再開始新錄音!", Toast.LENGTH_SHORT).show(); return; } //初始化臨時檔案物件 myFile = File.createTempFile ( "myAudio", //基本檔名 ".amr", //字尾 Environment.getExternalStorageDirectory() //目錄路徑 ); //建立錄音機物件 myMediaRecorder = new MediaRecorder(); //設定輸入裝置為麥克風 myMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); //設定輸出格式為預設的amr格式 myMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); //設定音訊編碼器為預設的編碼器 myMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); //設定輸出檔案的路徑 myMediaRecorder.setOutputFile(myFile.getAbsolutePath()); //準備錄音 myMediaRecorder.prepare(); //開始錄音 myMediaRecorder.start(); //設定錄音中標記為true recordFlag=true; //啟動一個執行緒進行計時 new Thread() { public void run() { while(recordFlag) { //計時器加一 countSecond++; //呼叫方法設定新時長 setTime(); //休息1000ms try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } catch (IOException e) { e.printStackTrace(); } } else if(v == ibStop){//按下停止按鈕 if(myFile != null&&myMediaRecorder!=null) { //停止錄音 myMediaRecorder.stop(); //釋放錄音機物件 myMediaRecorder.release(); //將錄音機物件引用設定為null myMediaRecorder = null; } //設定錄音中標記為false recordFlag=false; //計時器清0 countSecond=0; //呼叫方法設定新時長 setTime(); } } //設定顯示時間的方法 public void setTime() { //計算分鐘和秒 int second=countSecond%60; int minute=countSecond/60; //建立內容字串 String msgStr=minute+"m:"+second+"s"; //建立訊息資料Bundle Bundle b=new Bundle(); //將內容字串放進資料Bundle中 b.putString("msg", msgStr); //建立訊息物件 Message msg=new Message(); //設定資料Bundle到訊息中 msg.setData(b); //設定訊息的what值 msg.what=UPDATE_TIME; //傳送訊息 hd.sendMessage(msg); }
最後注意要 宣告許可權!!!!
=================================================================================
Demo2 照相機
重點分析: Uri 的臨時儲存 由於使用了startActivityForResult來發送intent的所有必須要實現該方法 自定義的圖片儲存進手機快閃記憶體的方法 flush 方法
照片路徑處理的工具類程式碼
public class StoreFileUtil { //當前儲存照片對應的檔案 static File currFile; //獲取下一個可以儲存的檔案 public static File nextFile() { //獲取快閃記憶體卡路徑 String path= Environment.getExternalStorageDirectory().getAbsolutePath(); //尋找可以使用的檔名 int c=0; File fTest=new File(path+"/mc"+c+".jpg"); while(fTest.exists()) { c++; fTest=new File(path+"/mc"+c+".jpg"); } currFile=fTest; return fTest; } //臨時檔案 public static File tempFile() { //獲取快閃記憶體卡路徑 String path= Environment.getExternalStorageDirectory().getAbsolutePath(); File fTest=new File(path+"/BNtemp.jpg"); return fTest; }
Activity程式碼
@SuppressLint("HandlerLeak")
public class MyCameraActivity extends Activity
{
private static int REQUEST_ORIGINAL=0;// 請求圖片訊號標識
private Button photo;//拍照按鈕
private Button save;//儲存按鈕
private ImageView picture;//用於顯示圖片的ImageView
public static Bitmap bitmap;//當前拍的照片
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//獲取顯示圖片的ImageView
picture = (ImageView) findViewById(R.id.picture_imageView);
//獲取拍照按鈕
photo = (Button) findViewById(R.id.main_Button_paizhao);
//給拍照按鈕新增監聽器
photo.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
//呼叫系統相機的Intent
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//臨時照片檔案的位置
Uri uri = Uri.fromFile(StoreFileUtil.tempFile());
//將照片檔案的位置傳入intent
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
//發出intent啟動系統相機
startActivityForResult(intent, REQUEST_ORIGINAL);
}
});
//儲存按鈕
save = (Button) findViewById(R.id.main_Button_baocun);
//為儲存按鈕新增監聽器
save.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if(bitmap==null)
{
Toast.makeText(MyCameraActivity.this, "請先拍照再儲存!", Toast.LENGTH_SHORT) .show();
}
//儲存照片
setInSDBitmap(bitmap);
Toast.makeText(MyCameraActivity.this, "儲存成功:"+StoreFileUtil.currFile.getName()+"!", Toast.LENGTH_SHORT) .show();
}
});
}
//系統相機返回時的回撥方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK)
{
if(requestCode == REQUEST_ORIGINAL)
{
//從臨時照片檔案的位置載入照片
bitmap=BitmapFactory.decodeFile(StoreFileUtil.tempFile().getAbsolutePath());
//將圖片設定給ImageView顯示
picture.setImageBitmap(bitmap);
}
}
}
//將圖片儲存進手機快閃記憶體的方法
public static void setInSDBitmap(Bitmap bitmapToStore)
{
File file=StoreFileUtil.nextFile();
try
{
FileOutputStream fos=new FileOutputStream(file);
bitmapToStore.compress(Bitmap.CompressFormat.JPEG, 70, fos);
fos.flush();
fos.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
//重寫返回按鈕按下的處理方法
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_BACK)
{
finish();
}
return false;
}