Android 錄音與播放功能的簡(jiǎn)單實(shí)例
Android 錄音與播放功能的簡(jiǎn)單實(shí)例
最近在研究Android中一些常用的功能,像地圖、拍照、錄音和播放的實(shí)現(xiàn)等等,還有一些側(cè)滑、動(dòng)畫(huà)等是如何實(shí)現(xiàn)的。
今天就把錄音和播放的實(shí)現(xiàn)分享一下,錄音和播放比較簡(jiǎn)單,利用android內(nèi)部的類(lèi)即可實(shí)現(xiàn)。
1、先看下運(yùn)行后的界面:
以下三張圖分別是進(jìn)入、錄音、播放時(shí)的。



2、Layout布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="@drawable/switcherbar_bg"
android:gravity="center"
android:text="@string/audio_record_title"
android:textColor="#ffffff"
android:textSize="16sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical"
android:paddingLeft="10dip"
android:paddingRight="10dip" >
<TextView
android:id="@+id/audio_record_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="00:00" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:orientation="horizontal" >
<Button
android:id="@+id/audio_record_start"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/searchbtn_normal"
android:text="開(kāi)始錄音"
android:textSize="14sp" />
<Button
android:id="@+id/audio_record_stop"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_weight="1"
android:background="@drawable/searchbtn_bg"
android:text="結(jié)束錄音"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:orientation="horizontal" >
<Button
android:id="@+id/audio_record_play"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/searchbtn_normal"
android:text="播放錄音"
android:textSize="14sp" />
<Button
android:id="@+id/audio_record_select"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_weight="1"
android:background="@drawable/searchbtn_bg"
android:text="確定選擇"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
3 Activity類(lèi)
錄音涉及到二個(gè)Activity,第一個(gè)Activity比較簡(jiǎn)單,我這里大概說(shuō)下,其實(shí)就是有個(gè)按鈕,點(diǎn)擊后轉(zhuǎn)移第二個(gè)Activity,錄音返回后,在第一個(gè)Activity中獲取錄音的文件名、時(shí)長(zhǎng)等。
第一個(gè)Activity部分代碼:
// 錄音事件
ksly_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MaintainVisitEditActivity.this, AudioRecordActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra("duration", entity.getVoiceDuration());
intent.putExtra("fileName", entity.getVoiceRecord());
startActivityForResult(intent, VOICE_RECODE);
}
});
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == VOICE_RECODE && resultCode == AudioRecordActivity.SUCCESS) {
entity.setVoiceDuration(data.getLongExtra("duration", 0));// 時(shí)長(zhǎng)
entity.setVoiceRecord(data.getStringExtra("fileName"));// 文件名(絕對(duì)路徑)
ksly_time.setText(DateTimeUtils.formatToMillisecond(entity.getVoiceDuration()));
}
}
第二個(gè)Activity代碼:
這里要注意一下,就是需要捕獲返回鍵,處理一下,就是點(diǎn)擊返回鍵時(shí),也返回個(gè)狀態(tài)碼,以表示沒(méi)有錄音成功。
package com.whowii.ct.cm.activity;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.whowii.ct.cm.R;
import com.whowii.ct.cm.command.QueryParams;
import com.whowii.ct.cm.utils.DateTimeUtils;
import com.whowii.ct.cm.utils.SDCardUtils;
/**
* 錄制音頻
*
* @author Administrator
*
*/
public class AudioRecordActivity extends Activity {
private TextView audio_record_time;
private Button audio_record_start, audio_record_stop, audio_record_play, audio_record_select;
private MediaRecorder mediaRecorder;
private final String TAG = AudioRecordActivity.class.getSimpleName();
private boolean isIdle = true;// 當(dāng)前是否空閑,false:表示正在錄音
private long startTime = 0, stopTime = 0, duration = 0;// 開(kāi)始時(shí)間、結(jié)束時(shí)間、錄音時(shí)長(zhǎng)
private String fileName = null;// 存儲(chǔ)錄音文件的路徑
private Timer timer = null;// Timer計(jì)時(shí)器
public static final int SUCCESS = 1;// 錄制成功;
public static final int FAILURE = 0;// 錄制失敗
private MediaPlayer mediaPlayer;
private TimerTask task = new TimerTask() {
final Handler handler = new Handler() {
public void handleMessage(Message message) {
Bundle data = message.getData();
audio_record_time.setText(DateTimeUtils.formatToMillisecond(data.getLong("time")));
}
};
public void run() {
Message message = new Message();
long t = System.currentTimeMillis();
Bundle data = new Bundle();
data.putLong("time", t - startTime);
message.setData(data);
handler.sendMessage(message);
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); // 設(shè)置無(wú)標(biāo)題欄
setContentView(R.layout.audio_record);
mediaPlayer = new MediaPlayer();
initControl();
setListener();
timer = new Timer(true);
fileName = getIntent().getStringExtra("fileName");
duration = getIntent().getLongExtra("duration", 0);
}
private void initControl() {
audio_record_time = (TextView) findViewById(R.id.audio_record_time);
audio_record_start = (Button) findViewById(R.id.audio_record_start);
audio_record_stop = (Button) findViewById(R.id.audio_record_stop);
audio_record_play = (Button) findViewById(R.id.audio_record_play);
audio_record_select = (Button) findViewById(R.id.audio_record_select);
}
private void setListener() {
// 播放完成事件
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
isIdle = true;
audio_record_play.setText("播放錄音");
audio_record_play.setBackgroundResource(R.drawable.searchinput_bg);
}
});
// 開(kāi)始錄音
audio_record_start.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (!isIdle) {
return;
}
if (!SDCardUtils.sdCardExists()) {
Toast.makeText(AudioRecordActivity.this, "缺少SD卡,請(qǐng)先插入后再操作!", Toast.LENGTH_LONG).show();
return;
}
audio_record_start.setText("開(kāi)始錄音");
audio_record_start.setEnabled(true);
duration = 0;
startTime = System.currentTimeMillis();
fileName = QueryParams.CACHE_AUDIO_PATH;
fileName += new SimpleDateFormat("yyyyMMdd_hhmmss").format(new Date(startTime)) + ".amr";
File file = new File(fileName);
mediaRecorder = new MediaRecorder();
mediaRecorder.setOutputFile(file.getAbsolutePath());
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mediaRecorder.prepare();
mediaRecorder.start();
isIdle = false;
audio_record_start.setBackgroundResource(R.drawable.searchbtn_pressed);
timer.schedule(task, 0, 100);
} catch (IOException e) {
startTime = 0;
Log.e(TAG, e.toString());
Toast.makeText(AudioRecordActivity.this, "錄制時(shí)發(fā)生異常!", Toast.LENGTH_LONG).show();
}
}
});
// 結(jié)束錄音
audio_record_stop.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mediaRecorder != null) {
stopTime = System.currentTimeMillis();
duration = stopTime - startTime;
timer.cancel();
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
audio_record_start.setBackgroundResource(R.drawable.searchbtn_normal);
isIdle = true;
}
}
});
// 播放錄音
audio_record_play.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (!isIdle) {
return;
}
if (audio_record_play.getText().equals("播放錄音")) {
if (fileName == null || fileName.equals("") || duration == 0) {
Toast.makeText(AudioRecordActivity.this, "沒(méi)有錄音文件!", Toast.LENGTH_LONG).show();
return;
}
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(fileName);
mediaPlayer.prepare();
mediaPlayer.start();
isIdle = false;
audio_record_play.setText("終止播放");
audio_record_play.setBackgroundResource(R.drawable.searchbtn_pressed);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(AudioRecordActivity.this, "播放錄音時(shí)遇到錯(cuò)誤!", Toast.LENGTH_LONG).show();
}
} else {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.stop();
isIdle = true;
}
audio_record_play.setText("播放錄音");
audio_record_play.setBackgroundResource(R.drawable.searchinput_bg);
}
}
});
// 確認(rèn)選擇
audio_record_select.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (fileName == null || fileName.equals("") || duration == 0) {
Toast.makeText(AudioRecordActivity.this, "沒(méi)有錄音文件!", Toast.LENGTH_LONG).show();
return;
}
Intent intent = new Intent();
intent.putExtra("fileName", fileName);
intent.putExtra("duration", duration);
setResult(SUCCESS, intent);// 返回成功標(biāo)識(shí)
isIdle = true;
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
mediaPlayer = null;
}
finish();// 結(jié)束當(dāng)前的activity,等于點(diǎn)擊返回按鈕
}
});
}
// 捕獲返回鍵,關(guān)閉當(dāng)前頁(yè)面時(shí)返回失敗標(biāo)識(shí)
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
setResult(FAILURE);
isIdle = true;
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
mediaPlayer = null;
}
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
- Android一個(gè)類(lèi)實(shí)現(xiàn)錄音與播放實(shí)例
- 詳解Android開(kāi)發(fā)錄音和播放音頻的步驟(動(dòng)態(tài)獲取權(quán)限)
- Android實(shí)現(xiàn)語(yǔ)音播放與錄音功能
- Android編程實(shí)現(xiàn)錄音及保存播放功能的方法【附demo源碼下載】
- android語(yǔ)音即時(shí)通訊之錄音、播放功能實(shí)現(xiàn)代碼
- Android使用MediaRecorder實(shí)現(xiàn)錄音及播放
- Android錄音播放管理工具
- Android實(shí)現(xiàn)自制和播放錄音程序
- Android編程開(kāi)發(fā)錄音和播放錄音簡(jiǎn)單示例
- Android實(shí)現(xiàn)音頻錄音與播放
相關(guān)文章
Kotlin協(xié)程flowOn與線(xiàn)程切換超詳細(xì)示例介紹
這篇文章主要介紹了Kotlin協(xié)程flowOn與線(xiàn)程切換,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-09-09
Android進(jìn)階CoordinatorLayout協(xié)調(diào)者布局實(shí)現(xiàn)吸頂效果
這篇文章主要為大家介紹了Android進(jìn)階CoordinatorLayout協(xié)調(diào)者布局實(shí)現(xiàn)吸頂效果,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
Android UI實(shí)現(xiàn)SlidingMenu側(cè)滑菜單效果
這篇文章主要為大家詳細(xì)介紹了Android UI實(shí)現(xiàn)SlidingMenu側(cè)滑菜單效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12
Android 簡(jiǎn)單實(shí)現(xiàn)一個(gè)流式布局的示例
本篇文章主要介紹了Android 簡(jiǎn)單實(shí)現(xiàn)一個(gè)流式布局的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
android notification 的總結(jié)分析
notification是一種出現(xiàn)在任務(wù)欄的提示,特別是在4.0以后notification改進(jìn)了不少,本文內(nèi)容都是基于4.0及4.1以后總結(jié)來(lái)的2013-05-05
android實(shí)現(xiàn)主動(dòng)連接和被動(dòng)連接的藍(lán)牙聊天功能
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)主動(dòng)連接和被動(dòng)連接的藍(lán)牙聊天功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06

