Quantcast
Viewing all articles
Browse latest Browse all 5930

Android 仿QQ/微信语音功能。

简单仿照一个语音效果,效果图:
Image may be NSFW.
Clik here to view.
效果图

所以,首先先做一个Dialog用于展示我们说话的UI:
VoiceDialogManager.java

/**
 * 语音Dialog  管理器
 * Created by Administrator on 2017/2/28 0028.
 */

public class VoiceDialogManager {

    private Dialog dialog;
    private Context context;
    private ImageView dialog_iv_icon;
    private AnimationDrawable anim;

    public VoiceDialogManager(Context context) {
        this.context = context;
        init();
    }

    /**
     * Dialog初始化方法
     */
    private void init() {
        dialog = new Dialog(context, R.style.DialogThemes);
        View inflate = LayoutInflater.from(context).inflate(R.layout.dialog_voice_manager, null);
        dialog.show();
        dialog.setContentView(inflate);
        dialog_iv_icon = (ImageView) dialog.findViewById(R.id.dialog_iv_icon);
        dialog_iv_icon.setBackgroundResource(R.drawable.frame);
        anim = (AnimationDrawable) dialog_iv_icon.getBackground();
        anim.start();
        Window dialogWindow = dialog.getWindow();
        WindowManager.LayoutParams lp = dialogWindow.getAttributes();
        dialogWindow.setGravity(Gravity.BOTTOM /**| Gravity.TOP*/);
        //lp.x = 100; // 新位置X坐标
        lp.y = 100; // 新位置Y坐标
        lp.width = dp2px(260); // 宽度
        lp.height = dp2px(260); // 高度
        lp.alpha = 0.7f; // 透明度
        dialogWindow.setAttributes(lp);

    }

    private int dp2px(int dpValue) {
        return (int) context.getResources().getDisplayMetrics().density * dpValue;
    }

    public void show() {
        if (dialog != null) {
            dialog.show();
        }
    }

    public void dismiss() {
        if (dialog != null) {
            anim.stop();
            dialog.dismiss();
            anim = null;
            dialog = null;
        }
    }

}

用到的布局文件:
dialog_voice_manager.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/shape"
    android:gravity="center"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/dialog_iv_icon"
        android:layout_width="90dp"
        android:layout_height="90dp"
        android:layout_gravity="center" />

</LinearLayout>

布局文件用到的圆角背景:
shape.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <!-- 填充的颜色 -->
    <solid android:color="#ccc" />
    <!-- 设置按钮的四个角为弧形 -->
    <!-- android:radius 弧形的半径 -->
    <corners android:radius="15dip" />

    <!-- padding:View边界的间隔 -->
    <padding
        android:bottom="10dp"
        android:left="10dp"
        android:right="10dp"
        android:top="10dp" />
</shape>

frame动画xml

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item
        android:drawable="@drawable/voice1"
        android:duration="300" />
    <item
        android:drawable="@drawable/voice2"
        android:duration="300" />
    <item
        android:drawable="@drawable/voice3"
        android:duration="300" />

</animation-list>

语音动画图片资源:
Image may be NSFW.
Clik here to view.
v1

Image may be NSFW.
Clik here to view.
v2

Image may be NSFW.
Clik here to view.
v3

自此,一个语音动画的Dialog就已经完成了,那么我们下面继续真正录音的逻辑吧。

private MediaRecorder mediaRecorder;
private String mDir;
private String mFilePath;

    public void prepareAudio() {//录音准备
        try {
            File dir = new File(mDir);
            if (!dir.exists()) {
                dir.mkdirs();//先检查和创建目录
            }
            //文件名例:x8n232iej2e3u4h35hj453.amr
            String fileName = getFileName();//这里用时间戳或者UUID当做文件名
            File file = new File(dir, fileName);//这里dir获取手机内存或者SD卡路径
            mFilePath = file.getAbsolutePath();
            mediaRecorder = new MediaRecorder();
            //设置输出位置
            mediaRecorder.setOutputFile(file.getAbsolutePath());
            //设置麦克风为音源
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            //设置音频格式
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
            //设置音频编码amr
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            //准备
            mediaRecorder.prepare();
            //开始
            mediaRecorder.start();
        } catch (Exception e) {
            e.printStackTrace();
            //这里mediaRecorder会抛出异常,我们需要捕获,否则造成崩溃。
        }
    }

停止录音时释放资源:

    /**
     * 释放
     */
    public void release() {
        if (mediaRecorder != null) {
            mediaRecorder.stop();
            mediaRecorder.release();
            mediaRecorder = null;
        }
    }

有时候在录音不足1秒或者我们需要取消,我们需要删除取消的文件,所以再定义一个取消函数:

    /**
     * 取消
     */
    public void cancel() {
        release();
        if (mFilePath != null) {
            File file = new File(mFilePath);
            file.delete();
            mFilePath = null;
        }
    }

上述代码会把录音文件输出到我们指定的文件路径下,我们只需记录这个路径,然后播放就行了,对了,最后记得加上录音所需权限:

    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
作者:c__chao 发表于2017/2/28 15:11:19 原文链接
阅读:57 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>