Android 实现录音和监听声音大小实现话筒动画效果

公司项目做的差不多了,,闲下来了,,就写一篇关于android利用MediaRecorder实现录音的文章吧,并且录音的时候声音的大小可以控制话筒实现动画效果,
效果如图所示:
这里写图片描述
录音的文件最后保存在SD卡下名为”luyin.3gp”这个文件,
直接看代码咯:
主要就一个MainActivity:

import java.io.File;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
    //存储很多张话筒图片的数组
    private Drawable[] micImages;
    //话筒的图片
    private ImageView micImage;

    private RelativeLayout recordingContainer;
    private TextView recordingHint;
    private Button buttonPressToSpeak;
    private MediaRecorder recorder=null;
    //录音存储在SD卡的路径
    private String output_Path=Environment.getExternalStorageDirectory().getAbsolutePath()
            +File.separator+"luyin.3gp";
    //录音文件
    private File soundFile;
    private int BASE = 600;  
    private int SPACE = 200;// 间隔取样时间  


     private final Handler mHandler = new Handler(){
         public void handleMessage(android.os.Message msg) {
            int what=msg.what;
            //根据mHandler发送what的大小决定话筒的图片是哪一张
            //说话声音越大,发送过来what值越大
            if(what>13){
                what=13;
            }
             micImage.setImageDrawable(micImages[what]);
         };
     };  
        private Runnable mUpdateMicStatusTimer = new Runnable() {  
            public void run() {  
                updateMicStatus();  
            }  
        };  

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }

    private void init() {
        micImage=(ImageView) findViewById(R.id.mic_image);
        recordingHint=(TextView) findViewById(R.id.recording_hint);
        recordingContainer=(RelativeLayout) findViewById(R.id.recording_container);
        buttonPressToSpeak=(Button) findViewById(R.id.buttonPressToSpeak);
        buttonPressToSpeak.setOnTouchListener(new PressToSpeakListen());
        // 动画资源文件,用于录制语音时
        micImages = new Drawable[] { 
                getResources().getDrawable(R.drawable.record_animate_01),
                getResources().getDrawable(R.drawable.record_animate_02),
                getResources().getDrawable(R.drawable.record_animate_03),
                getResources().getDrawable(R.drawable.record_animate_04),
                getResources().getDrawable(R.drawable.record_animate_05),
                getResources().getDrawable(R.drawable.record_animate_06),
                getResources().getDrawable(R.drawable.record_animate_07),
                getResources().getDrawable(R.drawable.record_animate_08),
                getResources().getDrawable(R.drawable.record_animate_09),
                getResources().getDrawable(R.drawable.record_animate_10),
                getResources().getDrawable(R.drawable.record_animate_11),
                getResources().getDrawable(R.drawable.record_animate_12),
                getResources().getDrawable(R.drawable.record_animate_13),
                getResources().getDrawable(R.drawable.record_animate_14), };

    }

    /**
     * 按住说话listener
     * 
     */
    class PressToSpeakListen implements View.OnTouchListener {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (!isExitsSdcard()) { 
                    Toast.makeText(MainActivity.this, "未检测到SD卡", Toast.LENGTH_SHORT).show();
                    return false;
                }
                if(recorder!=null){
                    recorder.stop();
                    recorder.release();
                    recorder=null;
                }
                soundFile=new File(output_Path);
                recorder=new MediaRecorder();
                recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//声音来源是话筒
                recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//设置格式
                recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//设置解码方式
                recorder.setOutputFile(soundFile.getAbsolutePath());
                try {
                    recorder.prepare();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                recorder.start();
                updateMicStatus();
                    recordingContainer.setVisibility(View.VISIBLE);
                    recordingHint.setText("手指上滑,取消发送");
                    recordingHint.setBackgroundColor(Color.TRANSPARENT);
                    return true;
            case MotionEvent.ACTION_MOVE: {
                //在这里只是做了监听,并没有做与发送相关的处理
                if (event.getY() < 0) {
                    recordingHint.setText("松开手指,取消发送");
                    recordingHint.setBackgroundResource(R.drawable.recording_text_hint_bg);

                } else {
                    recordingHint.setText("手指上滑,取消发送");
                    recordingHint.setBackgroundColor(Color.TRANSPARENT);

                }
                return true;
            }
            case MotionEvent.ACTION_UP:
                //抬起手指,停止录音
                recordingContainer.setVisibility(View.INVISIBLE);
                 stopRecoder();
                 Toast.makeText(getApplicationContext(), "录音存储到了"+soundFile.getAbsolutePath(), 1).show();
                return true;
            default:

                return false;
            }
        }
    }
    private void stopRecoder(){
        if (soundFile != null && soundFile.exists())
        {
            // 停止录音
            recorder.stop();  
            // 释放资源
            recorder.release();  
            recorder = null;
        }
    }
     private void updateMicStatus() {  
         if(recorder!=null){
             int ratio = recorder.getMaxAmplitude() / BASE;  
             int db = 0;// 分贝   
             if (ratio > 1)  
                 db = (int) (20 * Math.log10(ratio));  
                System.out.println("分贝值:"+db+"     "+Math.log10(ratio));  
                //我对着手机说话声音最大的时候,db达到了35左右,
                mHandler.postDelayed(mUpdateMicStatusTimer, SPACE);  
                //所以除了2,为的就是对应14张图片
                mHandler.sendEmptyMessage(db/2);
         }
     }
    /**
     * 检测Sdcard是否存在
     * 
     * @return
     */
    public  boolean isExitsSdcard() {
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
            return true;
        else
            return false;
    }


}

然后是activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
  >
         <RelativeLayout
            android:id="@+id/recording_container"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:background="@drawable/recording_hint_bg"
            android:padding="10dp"
            android:visibility="invisible" >

            <ImageView
                android:id="@+id/mic_image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:src="@drawable/record_animate_01" />

            <TextView
                android:id="@+id/recording_hint"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/mic_image"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="5dp"
                android:padding="2dp"
                android:text="手指上滑,取消发送"
                android:textSize="10sp" />
        </RelativeLayout>

<Button
    android:id="@+id/buttonPressToSpeak"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="30dip"
    android:layout_centerHorizontal="true"
    android:text="摁下录音" />

</RelativeLayout>

最后不要忘了加权限:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄油奥特曼

如果可以,请我喝一杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值