Android录制声音文件(音频),并播放

本文提供了一个Android录音和播放声音的示例,包括权限设置、MediaRecorderUtils的使用、自定义MyChronometer以及PopupWindow的实现。在实际应用中需要注意权限问题,以及可能存在的崩溃风险,例如多次点击同一文件。提供了详细的代码结构和资源说明。
摘要由CSDN通过智能技术生成

readme:1、这个demo中没有对多次点击同一个声音文件做详细处理,偶尔会有崩溃,用的时候需要注意。2、按住录音按钮录音过程中,只对竖直方向处理了一下,水平方向没写;3、没有做删除某个声音文件的操作,但是测试的时候实现了功能,需要用到的话,在MainActivity—>onItemClick中的TODO中有详细说明;4、这只是个demo,如果要在项目中使用,先写出demo,没问题了,再引入项目,在写成demo后,在真机上运行的时候,如果出现获取录音权限,最好选择“允许”,如果拒绝,可能会崩溃。
记得打开手机运行录音的权限
先来效果图:
这里写图片描述

目录结构:

这里写图片描述

1、添加权限:

    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.CALL_PHONE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

2、新建MediaRecorderUtils,复制以下源码:

package com.chen.voicedemo;

import android.media.MediaRecorder;
import android.os.Handler;
import android.util.Log;
import android.widget.ImageView;

import java.io.File;

/**
 * 录音工具类
 */
public class MediaRecorderUtils {
   

    private static MediaRecorder recorder;
    static MediaRecorderUtils mediaRecorderUtils;
    static ImageView mimageView;
    private String path;

    /**
     * 获得单例对象,传入一个显示音量大小的imageview对象,如不需要显示可以传null
     */
    public static MediaRecorderUtils getInstence(ImageView imageView) {
        if (mediaRecorderUtils == null) {
            mediaRecorderUtils = new MediaRecorderUtils();
        }
        mimageView = imageView;
        return mediaRecorderUtils;
    }

    /**
     * 获得音频路径
     */
    public String getPath() {
        return path;
    }

    /**
     * 初始化
     */
    private void init() {

        recorder = new MediaRecorder();// new出MediaRecorder对象
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        // 设置MediaRecorder的音频源为麦克风  
        recorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
        // 设置MediaRecorder录制的音频格式  
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        // 设置MediaRecorder录制音频的编码为amr.  
        File file = new File(Utils.IMAGE_SDCARD_MADER);
        if (!file.exists()) {
            file.mkdirs();
        }
        path = Utils.IMAGE_SDCARD_MADER + Utils.getVoiceFileName() + "stock.amr";
        recorder.setOutputFile(path);
        // 设置录制好的音频文件保存路径  
        try {
            recorder.prepare();// 准备录制  
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 开始录音
     */
    public void MediaRecorderStart() {
        init();
        try {
            recorder.start();
            flag = true;
            if (mimageView != null) {
                updateMicStatus();
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("chen", "录制失败");
        }
    }

    /**
     * 停止录音
     */
    public void MediaRecorderStop() {
        try {
            recorder.stop();
            recorder.release(); //释放资源
            flag = false;
            mimageView = null;
            recorder = null;
        } catch (Exception e) {
            e.toString();
        }

    }

    /**
     * 删除已录制的音频
     */
    public void MediaRecorderDelete() {
        File file = new File(path);
        if (file.isFile()) {
            file.delete();
        }
        file.exists();
    }

    ;

    private final Handler mHandler = new Handler();
    private Runnable mUpdateMicStatusTimer = new Runnable() {
        public void run() {
            updateMicStatus();
        }
    };
    private int BASE = 1;
    private int SPACE = 1000;// 间隔取样时间
    private boolean flag = true;

    /**
     * 更新话筒状态
     */
    private void updateMicStatus() {
        if (recorder != null) {
            double ratio = (double) recorder.getMaxAmplitude() / BASE;
            double db = 0;// 分贝
            if (ratio > 1) {
                db = 20 * Math.log10(ratio);
            }
            int i = (int) db / 10;
            switch (i) {
                case 1:
                    mimageView.setImageResource(R.drawable.rc_ic_volume_1);
                    break;
                case 2:
                    mimageView.setImageResource(R.drawable.rc_ic_volume_2);
                    break;
                case 3:
                    mimageView.setImageResource(R.drawable.rc_ic_volume_3);
                    break;
                case 4:
                    mimageView.setImageResource(R.drawable.rc_ic_volume_4);
                    break;
                case 5:
                    mimageView.setImageResource(R.drawable.rc_ic_volume_5);
                    break;
                case 6:
                    mimageView.setImageResource(R.drawable.rc_ic_volume_6);
                    break;
                case 7:
                    mimageView.setImageResource(R.drawable.rc_ic_volume_7);
                    break;
                case 8:
                    mimageView.setImageResource(R.drawable.rc_ic_volume_8);
                    break;
            }
            if (flag) {
                mHandler.postDelayed(mUpdateMicStatusTimer, SPACE);
            }
        }
    }

}

3、创建MyChronometer,复制以下代码

package com
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值