Android 录音与播放功能的简单实例

 Android 录音与播放功能的简单实例

最近在研究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);
  } 

}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • Android使用MediaRecorder实现录音及播放

    现在项目中有使用到音视频相关技术,在参考了网上各种大牛的资料及根据自己项目实际情况(兼容安卓6.0以上版本动态权限管理等),把声音录制及播放相关代码做个记录. public class MediaRecorderActivity extends BaseActivity { private Button start_tv; private ListView listView; //线程操作 private ExecutorService mExecutorService; //录音API pri

  • Android编程开发录音和播放录音简单示例

    本文实例讲述了Android编程开发录音和播放录音的方法.分享给大家供大家参考,具体如下: /* * The application needs to have the permission to write to external storage * if the output file is written to the external storage, and also the * permission to record audio. These permissions must be

  • Android录音播放管理工具

    1.语音播放直接用系统工具就好了,这个就不多说了,根据传入的路径(网络路径或本地路径均可)播放音频文件 /** * Created by zhb on 2017/1/16. * 音乐在线播放 */ public class PlayManager { private Context mcontext; public PlayManager(Context context){ this.mcontext = context; } public void play(String song){ Med

  • Android实现自制和播放录音程序

    首先,让我们先看下实现的截图: 当有录音文件存在时,会显示在下面的ListView当中. 下面给出实现的完整代码: 1.主程序代码 package irdc.ex07_11; import java.io.File; import java.io.IOException; import java.util.ArrayList; import android.app.Activity; import android.content.Intent; import android.media.Medi

  • Android 录音与播放功能的简单实例

     Android 录音与播放功能的简单实例 最近在研究Android中一些常用的功能,像地图.拍照.录音和播放的实现等等,还有一些侧滑.动画等是如何实现的. 今天就把录音和播放的实现分享一下,录音和播放比较简单,利用android内部的类即可实现. 1.先看下运行后的界面: 以下三张图分别是进入.录音.播放时的. 2.Layout布局文件 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout

  • Android 实现圆角图片的简单实例

    Android 实现圆角图片的简单实例 实现效果图: 本来想在网上找个圆角的例子看一看,不尽人意啊,基本都是官方的Demo的那张原理图,稍后会贴出.于是自己自定义了个View,实现图片的圆角以及圆形效果.效果图: Android 圆角图片的实现形式,包括用第三方.也有系统的.比如makeramen:roundedimageview,系统的cardview , glide .fresco . compile 'com.android.support:appcompat-v7:24.0.0' com

  • Android Kotlin的使用及简单实例

    Android Kotlin的使用及简单实例 写在前面的话,作为一个不熬夜的人,一觉醒来发现Kotlin成为了Android的官方语言,可谓是大喜过望.为了趁热打铁,我决定提前三天放出原定本周日Release的文章.希望能及时让大家了解一下Kotlin. 相信很多开发人员,尤其是Android开发者都会或多或少听说过Kotlin,当然如果没有听过或者不熟悉也没有关系.因为本篇文章以及博客后期的内容会涉及到很多关于Kotlin的知识分享. 在写这篇文章前的一个多月,Flipboard中国的Andr

  • Android管理与操作Wifi简单实例源码

    因为需要一直在弄网络的问题,今天看了一下Wifi的操作,经过整理,做出来了一个类,可能不全,但是个人感觉已经完全能够满足需要了,当然,里面的方法也有可能是错误的或者是不全的,这个类我没有进行完整的测试,只测试了其中的一些方法. 其实操作Wifi也是很简单的,主要使用以下几个对象或变量: private WifiManager wifiManager;// 声明管理对象OpenWifi private WifiInfo wifiInfo;// Wifi信息 private List<ScanRes

  • Android使用SQLite数据库的简单实例

    先画个图,了解下Android下数据库操作的简单流程: 1.首先,写一个自己的数据库操作帮助类,这个类继承自Android自带的SQLiteOpenHelper. 2.在自己的DAO层借助自己的Helper写数据库操作的一些方法 3.Activity调用DAO层的数据库操作方法进行操作 下面例子是: 1.Helper 复制代码 代码如下: package cn.learn.db.util; import android.content.Context;import android.databas

  • Android 回调详解及简单实例

    Android  回调 前言: Android中的回调最经典的就是点击事件设置监听(一般通过switch(v.getId()))这里写个最基本的 btn_rigister.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // TODO log in } }); view对外暴露了一个接口onClick public interface OnClickListene

  • Android ContentProvider的实现及简单实例代码

    一.概念及说明 ContentProvider定义: 内容提供者是一个Android应用的基础模块,提供内容给这个应用,它们封装数据和提供它给应用通过这个ContentResolver接口,使用ContentProvider可以在不同的应用程序之间共享数据,android为常见的一些数据提供了ContentProvider(视频.音频),ContentProvider使用表的形式来组织数据. URI定义: 每一个ContentProvider都拥有一个公共的URI,这个URI用于表示这个Cont

  • Android  回调详解及简单实例

    Android  回调 前言: Android中的回调最经典的就是点击事件设置监听(一般通过switch(v.getId()))这里写个最基本的 btn_rigister.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // TODO log in } }); view对外暴露了一个接口onClick public interface OnClickListene

  • Android RecyclerView详解及简单实例

    Android  RecyclerView 小白今天第一次接触RecyclerView,前辈大神告诉我这是一个很神奇的控件,一看就是一整天. RecyclerView中有规定好的方法去显示列表,图片甚至视频.还带有删除新建某一列表的方法.相对于ListView这个 RecyclerView控件就更加牛了. 明白的大神看一眼就懂,小白可以自己照源码敲一遍看看效果.这段程序是把A-Z按列排列下来: package com.example.osserver.recycler; import andro

  • Android中AnimationDrawable使用的简单实例

    首先,可以在drawable文件夹下定义一个xml的文件.如下所示: 复制代码 代码如下: <animation-list xmlns:android="http://schemas.android.com/apk/res/android"    android:oneshot="true">    <item android:drawable="@drawable/compass_1" android:duration=&qu

随机推荐