Android仿微信录制语音功能
作者:L代码 发布时间:2022-10-18 15:54:18
标签:Android,微信,录制语音
本文实例为大家分享了Android仿微信录制语音的具体代码,供大家参考,具体内容如下
前言
我把录音分成了两部分
1.UI界面,弹窗读秒
2.一个类(包含开始、停止、创建文件名功能)
第一部分
由于6.0权限问题,点击按钮申请权限通过则弹窗,如何申请权限
弹窗布局popw_record.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:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="260dp"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:background="@drawable/take_phone"
android:orientation="vertical">
<ImageView
android:id="@+id/close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:padding="10dp"
android:src="@mipmap/guanbi" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/luyin" />
<Chronometer
android:id="@+id/timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:format="%s" />
<TextView
android:id="@+id/startRecord"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/playrecord"
android:layout_marginTop="20dp"
android:background="@color/background"
android:padding="10dp"
/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
弹弹弹
/**
* 开始录音
*/
private void showPopup() {
final View contentView = LayoutInflater.from(Orderdeatil.this).inflate(R.layout.popw_record, null);
mPopWindow = new PopupWindow(contentView, ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.WRAP_CONTENT, true);
mPopWindow.setContentView(contentView);
TextView startRe = (TextView) contentView.findViewById(R.id.startRecord);
startRe.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP://松开事件发生后执行代码的区域
if (mPopWindow != null) {
mPopWindow.dismiss();
sr.stopRecording();
}
break;
case MotionEvent.ACTION_DOWN://按住事件发生后执行代码的区域
Chronometer timer = (Chronometer) contentView.findViewById(R.id.timer);
timer.setBase(SystemClock.elapsedRealtime());//计时器清零
timer.start();//开始录音的提示
sr.startRecording();
break;
case MotionEvent.ACTION_CANCEL:
if (mPopWindow != null) {
mPopWindow.dismiss();
sr.stopRecording();//停止录音
}
break;
default:
break;
}
return true;
}
});
ImageView close = (ImageView) contentView.findViewById(R.id.close);
close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPopWindow.dismiss();
}
});
mPopWindow.setTouchable(true);
mPopWindow.setFocusable(true);
mPopWindow.setBackgroundDrawable(new BitmapDrawable());
mPopWindow.setOutsideTouchable(true);
mPopWindow.setTouchInterceptor(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
mPopWindow.dismiss();
return true;
}
return false;
}
});
View rootview = LayoutInflater.from(Orderdeatil.this).inflate(R.layout.activity_orderdeatil, null);
mPopWindow.showAtLocation(rootview, Gravity.CENTER, 0, 0);
}
第二部分 工具类
class SoundRecorder {
public void startRecording() {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mRecorder.setOutputFile(newFileName());
try {
// 准备好开始录音
mRecorder.prepare();
mRecorder.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void stopRecording() {
if (mRecorder != null) {
//added by ouyang start
try {
//下面三个参数必须加,不加的话会奔溃,在mediarecorder.stop();
//报错为:RuntimeException:stop failed
mRecorder.setOnErrorListener(null);
mRecorder.setOnInfoListener(null);
mRecorder.setPreviewDisplay(null);
mRecorder.stop();
} catch (IllegalStateException e) {
// TODO: handle exception
Log.i("Exception", Log.getStackTraceString(e));
} catch (RuntimeException e) {
// TODO: handle exception
Log.i("Exception", Log.getStackTraceString(e));
} catch (Exception e) {
// TODO: handle exception
Log.i("Exception", Log.getStackTraceString(e));
}
//added by ouyang end
mRecorder.release();
mRecorder = null;
upRecord();
}
}
public String newFileName() {
mFileName = Environment.getExternalStorageDirectory()
.getAbsolutePath();
String s = new SimpleDateFormat("yyyy-MM-dd hhmmss")
.format(new Date());
return mFileName += "/rcd_" + s + ".mp3";
}
}
这是从我代码中择出来的,加上权限应该是可以的。
来源:https://blog.csdn.net/qq_34882418/article/details/81346299
0
投稿
猜你喜欢
- Java 判断字符串是否为IP地址,供大家参考,具体内容如下1、代码主要就是这么几个条件非空长度符合 0.0.0.0 - 255.255.2
- 在Java的内存分配中,总共3种常量池:Java 常量池详解(二)class文件常量池 和 Java 常量池详解(三)class运行时常量池
- 概述状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。这个模式将状态封装成独立的类,并将动作委托到 代表当前状态的对
- 前言我们之前学的单链表,默认只能从链表的头部遍历到链表的尾部,在实际中应用太少见,太局限;而双向链表,对于该链表中的任意节点,既可以通过该节
- git仓库直达List<String> strings = Lists.newArrayList("name=kk&q
- 一、递归概念递归本质:程序调用自身的编程技巧叫做递归。程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言
- 前言之前在SpringBoot项目中简单使用定时任务,不过由于要借助cron表达式且都提前定义好放在配置文件里,不能在项目运行中动态修改任务
- 今天遇到文件上传的问题,使用Ajax方式进行提交,服务器一直报错The current request is not a multipart
- 记录web项目部署到阿里云服务器步骤(使用 web项目、阿里云服务器、Xftp、Xshell),敬请参考和指正1.将要部署的项目打包成WAR
- 写在前面注:本文章使用的 SpringBoot 版本为 2.2.4.RELEASE,其 Spring 版本为 5.2.3.RELEASE前言
- 在后端数据接口项目开发中,经常遇到返回的数据中有null值,导致前端需要进行判断处理,否则容易出现undefined的情况,如何便捷的将nu
- 简单工厂模式介绍:概要:简单工厂模式,又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模
- ThreadLocal与线程成员变量还有区别,ThreadLocal该类提供了线程局部变量。这个局部变量与一般的成员变量不一样,Thread
- 常用,记录一下。效果图:首先新建xml文件 bg_gradient.xml<?xml version="1.0&
- 第1 部分 hashCode的作用Java集合中有两类,一类是List,一类是Set他们之间的区别就在于List集合中的元素师有序的,且可以
- using System; using System.IO; public class FileApp { &nbs
- 本文实例为大家分享了Java Socket实现多人聊天系统的具体代码,供大家参考,具体内容如下前言GitHub地址开发环境:Eclipse
- 批量添加,批量更新之前判断是否已经存在批量添加之前判断是否已经存在,foreach separator用UNION ALL。批量
- 这里来讲一下后台java如何构造多叉树,这样前台就可接收到数据递归构造树形菜单了。我们来理一下如何实现构造多叉树的逻辑吧,其实整个问题概括起
- String replace replaceFirst repaceAll区别replace(char oldChar, char newC