Android 录音、播放功能的实现

本文介绍了一个简单的Android应用,用于实现录音与播放功能。通过使用Android内置类,该应用能够进行录音并显示实时录音时间,并提供了播放录音文件的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在研究android中一些常用的功能,像地图、拍照、录音和播放的实现等等,还有一些侧滑、动画等是如何实现的。

今天就把录音和播放的实现分享一下,录音和播放比较简单,利用android内部的类即可实现。

1、先看下运行后的界面:

以下三张图分别是进入、录音、播放时的。

  


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="开始录音"
                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="结束录音"
                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类

录音涉及到二个Activity,第一个Activity比较简单,我这里大概说下,其实就是有个按钮,点击后转移第二个Activity,录音返回后,在第一个Activity中获取录音的文件名、时长等。

第一个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));// 时长
			entity.setVoiceRecord(data.getStringExtra("fileName"));// 文件名(绝对路径)
			ksly_time.setText(DateTimeUtils.formatToMillisecond(entity.getVoiceDuration()));
		}
	}

第二个Activity代码:

这里要注意一下,就是需要捕获返回键,处理一下,就是点击返回键时,也返回个状态码,以表示没有录音成功。

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;// 当前是否空闲,false:表示正在录音
	private long startTime = 0, stopTime = 0, duration = 0;// 开始时间、结束时间、录音时长
	private String fileName = null;// 存储录音文件的路径
	private Timer timer = null;// Timer计时器
	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); // 设置无标题栏

		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);
			}
		});
		// 开始录音
		audio_record_start.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (!isIdle) {
					return;
				}
				if (!SDCardUtils.sdCardExists()) {
					Toast.makeText(AudioRecordActivity.this, "缺少SD卡,请先插入后再操作!", Toast.LENGTH_LONG).show();
					return;
				}
				audio_record_start.setText("开始录音");
				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, "录制时发生异常!", Toast.LENGTH_LONG).show();
				}
			}
		});
		// 结束录音
		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, "没有录音文件!", 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, "播放录音时遇到错误!", 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);
				}
			}
		});
		// 确认选择
		audio_record_select.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (fileName == null || fileName.equals("") || duration == 0) {
					Toast.makeText(AudioRecordActivity.this, "没有录音文件!", Toast.LENGTH_LONG).show();
					return;
				}

				Intent intent = new Intent();
				intent.putExtra("fileName", fileName);
				intent.putExtra("duration", duration);
				setResult(SUCCESS, intent);// 返回成功标识
				isIdle = true;
				if (mediaPlayer != null) {
					if (mediaPlayer.isPlaying()) {
						mediaPlayer.stop();
					}
					mediaPlayer = null;
				}
				finish();// 结束当前的activity,等于点击返回按钮
			}
		});
	}

	// 捕获返回键,关闭当前页面时返回失败标识
	@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);
	}

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值