主要实现的功能大的类有两个:MediaPlayer和MediaRecorder类。功能描述:先通过录音程序录一段语音存放到手机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.打开录音的界面:

android线程录音 安卓开发录音_android线程录音






































B.点击录音按钮界面:

android线程录音 安卓开发录音_android线程录音_02














































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

android线程录音 安卓开发录音_android线程录音_03



android线程录音 安卓开发录音_权限问题_04




































































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

android线程录音 安卓开发录音_权限问题_05





































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

android线程录音 安卓开发录音_Intent_06





































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

android线程录音 安卓开发录音_Android_07





































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

android线程录音 安卓开发录音_Intent_08






































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

android线程录音 安卓开发录音_Intent_09





































(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之间赋值问题。