使用Android开发录音和播放功能小程序示例

主要实现的功能大的类有两个:MediaPlayerMediaRecorder类。功能描述:先通过录音程序录一段语音存放到手机SD卡的指定目录里,通过ListView显示录音文件内容,点击录音文件进入播放小程序,播放选中的录音文件播放、暂停、停止功能,中使用了Intent类实现两个Activity之间数据传递(录音文件路径)

下面通过一个Samples10_2程序具体实现如上功能:

(1)新建一个Android Application Project项目取名为Samples10_2

(2)在res/layout文件修改activity_main.xml主布局文件(主要是添加两个按钮控件,录音停止按钮):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >


    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />


    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >


        <Button
            android:id="@+id/re_start"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="录音" />


        <Button
            android:id="@+id/re_stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="停止" />
    </LinearLayout>


    <ListView
        android:id="@+id/listView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
    </ListView>


</LinearLayout>

(3)因为要显示录音文件内容,通过在res/layout目录下添加一个file_list.xml布局文件,来实现显示当前录音文件的功能:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/linearLayout1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >


        <TextView
            android:id="@+id/fileName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="Large Text"
            android:textAppearance="?android:attr/textAppearanceLarge" />


    </LinearLayout>

(4)因为要实现录音内容的播放功能,在res/layout目录下添加一个play.xml布局文件(主要有三个按钮和一个显示标题的空间,播放暂停停止程序标题):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >


    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />


    <TextView
        android:id="@+id/mp3_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />


    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
    <Button
        android:id="@+id/play_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="播放" />


    <Button
        android:id="@+id/play_pause"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="暂停" />


    <Button
        android:id="@+id/play_stop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="停止" />


    </LinearLayout>
</LinearLayout>

(5)首先需要给程序必要的权限才能读/写、录制音频文件、创建删除文件、(联网)等权限。在程序的AndroidManifest.xml程序清单文件下添加如下权限:

<!--录制音频文件权限 --> 

<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>   
<!-- 在SDCard中创建与删除文件权限 --> 
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> 
<!-- 往SDCard写入数据权限 --> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<!-- 手机访问Internet权限 --> 

<uses-permission android:name="android.permission.INTERNET" />

因为Play.java类是另一个Activity所以还需要在AndroidMainifest.xml文件中添加这样一段代码(一般这里的类名需要写完整的类结构):

<activity android:name=".Play"></activity>

(6)下面就是两个Activity实现布局文件调用和具体功能的实现:MainActivity.java类(录音功能)和Play类(播放功能):

A.MainActivity.java类的具体实现:

package com.example.samples_10_2;


import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.Button;
import android.widget.ListView;
import java.io.File;
import android.media.MediaRecorder;
import android.os.Environment;
import android.app.AlertDialog;
import android.content.DialogInterface;
import java.io.File;
import java.util.List;
import java.util.HashMap;
import java.util.ArrayList;
import android.widget.SimpleAdapter;
import android.view.View;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView;
import android.content.Intent;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnErrorListener;


public class MainActivity extends Activity {
private Button startButton=null;//播放Button组件对象
private Button stopButton=null;//停止播放Button组件对象
private ListView listView=null;//用于显示文件列表的ListView组件对象
private File[] files=null;//File数组
private String dirPath="";//文件读/写指定目录
private MediaRecorder mediaRecorder=null;//创建一个空的MediaRecorder对象
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startButton=(Button)this.findViewById(R.id.re_start);//实例化播放Button组件对象
        stopButton=(Button)this.findViewById(R.id.re_stop);//实例化停止播放Button组件对象
        listView=(ListView)this.findViewById(R.id.listView);//实例化ListView组件对象
        stopButton.setEnabled(false); //停止按钮失效
        setListViewData(); //为ListView填充数据
        startButton.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View arg0) {
// 调用录音方法
startRecord();
}
});
        stopButton.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View arg0) {
//调用停止录音方法
stopRecord();
}
});
        listView.setOnItemClickListener(new OnItemClickListener() {
        //为ListView添加单击监听 实现点击录音文件转跳到另一个程序的功能
        @Override
     public void onItemClick(AdapterView<?> arg0 , View arg1, int arg2, long arg3)
     {
     Intent intent=new Intent();//初始化Intent
     intent.setClass(MainActivity.this, Play.class);//指定Intent对象启动的类
     intent.putExtra("filePath", files[arg2].getPath());//函数传递
     MainActivity.this.startActivity(intent);//启动新的Activity

     }
});
        
        
    }
    /**
     * 开始录音的方法
     */
    public void startRecord()
    {
    //获取录音文件路径
    String path=getRecordFilePath();//获取录音文件路径
    if(!"".equals(path))
    {
    mediaRecorder=new MediaRecorder();//实例化MediaRecorder
    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);//设置音频源
    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);//设置输出格式
    mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);//设置音频编码器
    mediaRecorder.setOutputFile(path);//设置输出路径

    }
    //文件录制错误监听
    mediaRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() {

@Override
public void onError(MediaRecorder arg0, int arg1, int arg2) {
if(mediaRecorder!=null)
{
//解除资源与mediaRecorder的赋值关系,让资源可以为其他程序利用
mediaRecorder.release();
}
}
});
    try
    {
    mediaRecorder.prepare();//准备
    mediaRecorder.start();//开始录音
    startButton.setEnabled(false);//录音按钮失效
    stopButton.setEnabled(true);//停止按钮生效
    startButton.setText("录音中…");
    }catch(Exception e)
    {
    e.printStackTrace();
    }
    }
    /**
     * 停止录音的方法
     */
    public void stopRecord()
    {
    if(mediaRecorder!=null)
    {
    mediaRecorder.stop();//停止录音
    mediaRecorder.release();//释放资源
    startButton.setEnabled(true);//录音按钮生效
    startButton.setText("录音");
    stopButton.setEnabled(false);//停止按钮失效
    setListViewData();//录音完成重新为ListView填充数据
    }
    }
    /**
     * 获取录音文件的路径
     * @return
     */
    public String getRecordFilePath()
    {
    String filePath="";//声明文件路径
    boolean sdCardState=getStorageState();//获取sdCard状态
    if(!sdCardState)
    {
    return filePath;//返回空字符串路径
    }
   
    String sdCardPath=Environment.getExternalStorageDirectory().getPath();//获取sdCard根目录路径
    File dirFile=new File(sdCardPath+File.separator+"recording");//自定义的录音文件File文件对象
    if(!dirFile.exists())
    {
    dirFile.mkdir();//不存在创建文件夹
    }
    try
    {
    //创建一个前缀为test后缀为.amr的录音文件,使用createTempFile方法来创建是为了避免文件冲突
    filePath=File.createTempFile("test",".amr",dirFile).getAbsolutePath();
    }catch(Exception e)
    {
    e.printStackTrace();
    }
    return filePath;//返回录音文件路径
    }
    /*
     * 为播放组件对象ListView填充数据
     */
    public void setListViewData()
    {
    boolean sdStatus=getStorageState();//调用获取手机sdCard的存储状态
    if(sdStatus)//判断sdCard的存储状态,如果是false提示并结束应用程序
    {
    File sdCardFile=Environment.getExternalStorageDirectory();//获取sdCard根目录File对象
    dirPath=sdCardFile.getPath()+File.separator+"recording";//指定文件存放目录
    File dirFile=new File(dirPath);
    if(!dirFile.exists())//判断文件存放目录是否存在
    {
    dirFile.mkdir();//不存在创建存放目录
    }
    files=dirFile.listFiles();//获取文件存放目录中的文件File对象
    List<HashMap<String,Object>> list=getList(files);//调用获取相应的集合
    setAdapter(list,files);//调用构造适配器并为ListView添加适配器
    }
    }
    /**
     * 根据File[]获取相应的集合
     * @param 
     * files File数组
     * @return
     * List<HashMap<String,Object>>
     */
    public List<HashMap<String,Object>> getList(File[] files)
    {
    List<HashMap<String,Object>> list=new ArrayList<HashMap<String,Object>>();//创建List集合
    for(int i=0;i<files.length;i++)//循环File数组
    {
    HashMap<String,Object> hashMap=new HashMap<String,Object>();//创建HashMap
    hashMap.put("file_name", files[i].getName());//往HashMap中添加文件名
    list.add(hashMap);//将HashMap添加到List集合中
    }
    return list;//返回List集合
    }
    /**
     * 构造适配器,为ListView添加适配器
     * @param list
     * @param files
     */
    public void setAdapter(List<HashMap<String,Object>> list,File[] files)
    {
    SimpleAdapter simpleAdapter=newSimpleAdapter(
    this, //android.content.Context上下文
    list, // java.util.List<? extends java.util.Map<java.lang.String, ?>>类型的List数据泛型
    R.layout.file_list,//int 布局数据
    new String[]{"file_name"},//java.lang.String[] 文件名称
    new int[]{R.id.fileName});//int[] TextView的Id
    listView.setAdapter(simpleAdapter);//为ListView添加适配器
    }
    /*
* 获取手机sd卡的存储状态
*/
    public boolean getStorageState()
    {
    if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))//判断手机sd卡的存储状态
    {
    return true;
    }else
    {
    new AlertDialog.Builder(this)//创建AlertDialog对象
    .setTitle("提示信息")//设置信息标题
    .setMessage("未安装SD卡,请检查你的设备")//设置信息内容
    .setPositiveButton("确认",new android.content.DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface arg0, int arg1) {
//结束应用程序
MainActivity.this.finish();
}
}).show();
    return false;
    }
   
    }
    
}

B.Play类的具体实现:

package com.example.samples_10_2;




import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.media.MediaPlayer;
import android.view.View.OnClickListener;
import android.os.Environment;
import java.io.File;
import android.net.Uri;
import android.media.MediaPlayer.OnCompletionListener;
import android.content.Intent;


public class Play extends Activity {
private MediaPlayer mediaPlayer = null; // 创建一个空MediaPlayer对象
private Button startButton = null; // 播放Button组件对象
private Button pauseButton = null; // 暂停Button组件对象
private Button stopButton = null; // 停止Button组件对象
private TextView nameTextView = null; // 文件名称TextView组件对象
private boolean isPause = false; // 是否暂停
private String filePath=null;//保存播放文件的路径
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.play);
        
        Intent intent=getIntent();
        Bundle bundle=intent.getExtras();
        filePath=bundle.get("filePath").toString();
        
        nameTextView=(TextView)this.findViewById(R.id.mp3_name);//实例化文件名称TextView组件对象
        nameTextView.setText(filePath); //设置文件名称
        startButton=(Button)this.findViewById(R.id.play_start); //实例化播放Button组件对象
        startButton.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// 调用Mp3播放方法
start();
}
});
        pauseButton=(Button)this.findViewById(R.id.play_pause);//实例化暂停Button组件对象
        pauseButton.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View arg0) {
//调用Mp3暂停方法
pause();
}
});
        stopButton=(Button)this.findViewById(R.id.play_stop);//实例化停止播放组件对象
        stopButton.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View arg0) {
// 调用Mp3停止播放方法
stop();
}
});
    }
    /**
     * Mp3开始播放
     */
    public void start()
    {
    try
    {
    if(mediaPlayer!=null)
    {
    if(mediaPlayer.isPlaying())//判断MediaPlayer对象正在播放中,并不执行一下程序
    {
    return;
    }
    }
    stop(); //调用停止播放方法
   
    if(isPause)//判断MediaPlayer对象是否暂停,如果暂停不重新播放
    {
    return;
    }
   
   
    // 加载资源文件中的MP3
     
     
    /*mediaPlayer=MediaPlayer.create(this, R.raw.becauseoflove);//加载资源文件中的MP3
    mediaPlayer.start();//开始播放
    */  

     
    //SD卡资源 
   
     
    mediaPlayer=new MediaPlayer();
    mediaPlayer.setDataSource(filePath);
    mediaPlayer.prepare();//准备播放
    mediaPlayer.start();//播放

 
    /*
    * 网络资源
    */
    /*mediaPlayer=new MediaPlayer();
    String path="http://music.baidu.com/data/music/file?link=http://yinyueshiting.baidu.com/data2/music/3566287/29237101437253261128.mp3?xcode=fc3ef977c9fa9bdf4394f800f7f2550e&song_id=2923710";
    Uri uri=Uri.parse(path);
    mediaPlayer=MediaPlayer.create(this, uri);
   
    mediaPlayer.setDataSource(path);//为MediaPlayer设置数据源
    mediaPlayer.prepare();//准备播放
    mediaPlayer.start();//开始播放
*/    

    //文件播放完毕监听
    mediaPlayer.setOnCompletionListener(new android.media.MediaPlayer.OnCompletionListener() {

@Override
public void onCompletion(MediaPlayer arg0) {
// 覆盖文件播出完毕事件
mediaPlayer.release();
startButton.setText("播放");
isPause=false;//取消暂停状态
mediaPlayer=null;
}
});
   
    //文件播放错误监听
    mediaPlayer.setOnErrorListener(new android.media.MediaPlayer.OnErrorListener() {

@Override
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
//解除资源与MediaPlayer的赋值关系,让资源可以为其他程序利用
arg0.release();
return false;
}
});
   
    startButton.setText("正在播放");
    pauseButton.setText("暂停");
   
    }catch(Exception e)
    {
    e.printStackTrace();
    }
    }
    /*
     * MP3暂停播放
     */
    public void pause()
    {
    try
    {
    if(mediaPlayer!=null)//判断MediaPlayer对象不为空
    {
    if(mediaPlayer.isPlaying())//判断MediaPlayer对象正在播放中
    {
    mediaPlayer.pause();//暂停播放
    pauseButton.setText("取消暂停");
    isPause=true;//暂停状态
    }else
    {
    mediaPlayer.start();//开始播放
    pauseButton.setText("暂停");
    isPause=false;
    }
    }
    }catch(Exception e)
    {
    e.printStackTrace();
    }
    }
    /*
     * MP3停止播放
     */
    public void stop()
    {
    try
    {
    if(mediaPlayer!=null)//判断MediaPlayer对象不为空
    {
    mediaPlayer.stop();//停止播放
    startButton.setText("播放");
    isPause=false;//取消暂停状态
    mediaPlayer.release();
    mediaPlayer=null;
    }
    }catch(Exception e)
    {
    e.printStackTrace();
    }
    }
    
}

(7)程序运行的结果如图所示:

A.打开录音的界面:







































B.点击录音按钮界面:















































C.点击停止录音按钮后界面:







































































D.多次点击录音停止按钮界面:






































E.点击刚才录音的音频文件转跳到Play Activity类界面:






































F.点击播放按钮显示界面:






































G.点击暂停按钮显示界面:







































H.点击停止播放按钮显示界面:






































(8)代码程序具体详解:

两个Activity通过Intent类进行交互(使用到的Bundle类)

在MainActiviy.java类中使用如下代码:

    Intent intent=new Intent();//初始化Intent
     intent.setClass(MainActivity.this, Play.class);//指定Intent对象启动的类
     intent.putExtra("filePath", files[arg2].getPath());//函数传递
     MainActivity.this.startActivity(intent);//启动新的Activity

将录音文件的路径存入到Bundle中的key-value键值对,使用startActivity(intent)函数实现转跳。

在Play.java类中使用如下代码,接收传递过过来的Bundle键值对,代码如下:

Intent intent=getIntent();
        Bundle bundle=intent.getExtras();
        filePath=bundle.get("filePath").toString();

至此所有录音和播放功能都已经介绍完成了,需要注意两个问题一个是权限问题,一个是Activity之间赋值问题。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值