推荐阅读:
SurfaceView+MediaPlayer封装之路
Android学习资源分享合集(1)

最近写了一个金额的语音播报功能,已封装成依赖库到Github,希望对大家有所帮助。
Github地址 :
https://github.com/javaexcept...

思路:
(1).准备音频文件。
(2).把要播报的金额转换成大写的金额,比如"零壹贰叁肆伍陆柒捌玖,分角 拾佰仟万拾佰仟亿拾佰仟万"的组合。
(3).通过MediaPlayer播放音频。


一.准备音频文件

下面是我音频文件,里面是大写的数字,为播报金额组合做准备。


二.金额转换

public class PlaySound {/*** 截取字符串** @param str  需要截取的字符串* @param idx1 开始位置* @param idx2 截止位置* @return 截取后的字符串*/public static String subString(String str, int idx1, int idx2) {try {return str.substring(idx1, idx2);} catch (Exception ex) {return "";}}/*** 传递一个字符串参数,如果是null返回“”字符串,否则去除前后的空格。** @param str 传入参数* @return 没有前后没有空格的字符串*/public static final String trim(String str) {if (str == null) return "";else return str.trim();}/*** 把double类型数据转换成有格式的字符串** @param d      需要转换的double类型数据* @param format 格式化方式* @return 有格式的字符串*/public static String formatDoubleToString(double d, String format) {String doubleStr = String.valueOf(d);java.text.DecimalFormat decf = new java.text.DecimalFormat(format);String formatStr = decf.format(d);/*** 通过java保留小数了* 如果转换前的长度>转换后的长度,Java的转换就有可能出错*/if (doubleStr.length() > formatStr.length()) {/*** 如果前面的都一致,但最后一位大于4就需要进位* 否则不进位*/if (formatStr.equals(doubleStr.substring(0, formatStr.length()))) {/*** 取转换前的后一位,* 有可能是“.”*/String followStr = doubleStr.substring(formatStr.length(), formatStr.length() + 1);if (".".equals(followStr)) {followStr = doubleStr.substring(formatStr.length() + 1, formatStr.length() + 2);}if (Integer.valueOf(followStr).intValue() > 4) {/*** 这个时候Java没有进位*/formatStr = decf.format(Double.valueOf(formatStr).doubleValue() + Double.valueOf(format.substring(0, format.length() - 1) + "1").doubleValue());}}}return formatStr;}/*** 把一个都money转换成大写的money** @param d 需要转换的money* @return 换成大写的money*/public static String capitalValueOf(double d) {String lowStr;int strLen;String currentStr;String upperPart;String upperStr = "";int index = 0;int findCount;String chns = "零壹贰叁肆伍陆柒捌玖";String units = "分角  拾佰仟万拾佰仟亿拾佰仟万";if (d >= 100000000 || d < 0) {return "";}if (d == 0) {return "零元整";}lowStr = trim(formatDoubleToString(d, "0.00"));strLen = lowStr.length();if (strLen == 0) {return "";}while (index < strLen) {currentStr = subString(lowStr, strLen - index - 1, strLen - index);if (".".equals(currentStr)) {upperPart = "元";} else {upperPart = subString(chns, Integer.valueOf(currentStr).intValue(), Integer.valueOf(currentStr).intValue() + 1);}upperPart += trim(subString(units, index, index + 1));upperStr = upperPart + upperStr;index += 1;}for (; ; ) {findCount = 0;if (upperStr.indexOf("拾零万零仟") < 0) {if (upperStr.indexOf("拾零万") >= 0) {if ("仟".equals(subString(upperStr, upperStr.indexOf("拾零万") + 4, upperStr.indexOf("拾零万") + 5))) {findCount++;upperStr = upperStr.replaceFirst("拾零万", "拾万零");}}}if (upperStr.indexOf("零元") >= 0) {findCount++;upperStr = upperStr.replaceAll("零元", "元");}if (upperStr.indexOf("零拾") >= 0) {findCount++;upperStr = upperStr.replaceAll("零拾", "零");}if (upperStr.indexOf("零佰") >= 0) {findCount++;upperStr = upperStr.replaceAll("零佰", "零");}if (upperStr.indexOf("零仟") >= 0) {findCount++;upperStr = upperStr.replaceAll("零仟", "零");}if (upperStr.indexOf("零万") >= 0) {findCount++;upperStr = upperStr.replaceAll("零万", "万");}if (upperStr.indexOf("零亿") >= 0) {findCount++;upperStr = upperStr.replaceAll("零亿", "亿");}if (upperStr.indexOf("零零") >= 0) {findCount++;upperStr = upperStr.replaceAll("零零", "零");}if (upperStr.indexOf("零角零分") >= 0) {findCount++;upperStr = upperStr.replaceAll("零角零分", "整");}if (upperStr.indexOf("零分") >= 0) {findCount++;upperStr = upperStr.replaceAll("零分", "整");}if (upperStr.indexOf("零角") >= 0) {findCount++;upperStr = upperStr.replaceAll("零角", "零");}if (upperStr.indexOf("零亿零万零元") >= 0) {findCount++;upperStr = upperStr.replaceAll("零亿零万零元", "亿元");}if (upperStr.indexOf("亿零万零元") >= 0) {findCount++;upperStr = upperStr.replaceAll("亿零万零元", "亿元");}if (upperStr.indexOf("零亿零万") >= 0) {findCount++;upperStr = upperStr.replaceAll("零亿零万", "亿");}if (upperStr.indexOf("零万零元") >= 0) {findCount++;upperStr = upperStr.replaceAll("零万零元", "万元");}if (upperStr.indexOf("万零元") >= 0) {findCount++;upperStr = upperStr.replaceAll("万零元", "万元");}if (findCount == 0) {break;}}while ("元".equals(subString(upperStr, 0, 1)) || "零".equals(subString(upperStr, 0, 1)) || "角".equals(subString(upperStr, 0, 1)) || "分".equals(subString(upperStr, 0, 1)) || "整".equals(subString(upperStr, 0, 1))) {strLen = upperStr.length();upperStr = subString(upperStr, 1, strLen);}return upperStr;}public static void main(String[] args){}}

三.MediaPlayer播放音频

1.MediaPlayer简介

MediaPlayer其实是一个封装的很好的音频、视频流媒体操作类,如果查看其源码,会发现其内部是调用的native方法,既然是一个流媒体操作类,那么必然涉及到,播放、暂停、停止等操作,实际上MediaPlayer也为我们提供了相应的方法来直接操作流媒体。
void start():开始或恢复播放。

void stop():停止播放。

void pause():暂停播放。 

通过上面三个方法,只要设定好流媒体数据源,即可在应用中播放流媒体资源,为了更好的操作流媒体,MediaPlayer还为我们提供了一些其他的方法,这里列出一些常用的,详细内容参阅官方文档。
int getDuration():获取流媒体的总播放时长,单位是毫秒。

int getCurrentPosition():获取当前流媒体的播放的位置,单位是毫秒。

void seekTo(int msec):设置当前MediaPlayer的播放位置,单位是毫秒。

void setLooping(boolean looping):设置是否循环播放。

boolean isLooping():判断是否循环播放。

boolean isPlaying():判断是否正在播放。

void prepare():同步的方式装载流媒体文件。

void prepareAsync():异步的方式装载流媒体文件。

void release ():回收流媒体资源。

void setAudioStreamType(int streamtype):设置播放流媒体类型。

void setWakeMode(Context context, int mode):设置CPU唤醒的状态。

setNextMediaPlayer(MediaPlayer next):设置当前流媒体播放完毕,下一个播放的MediaPlayer。

在使用start()播放流媒体之前,需要装载流媒体资源。

2.MediaPlayer实现播报源码

public class VoiceUtils {private static volatile VoiceUtils singleton = null;public    boolean IsPlaying;MediaPlayer mediaPlayer=null;private Context mContext;public VoiceUtils(Context context) {this.mContext = context.getApplicationContext();}/*** 单例* @param context* @return*/public static VoiceUtils with(Context context){if (singleton == null) {synchronized (VoiceUtils.class) {if (singleton == null) {singleton = new VoiceUtils(context);}}}return singleton;}public void SetIsPlay( boolean IsPlaying){this.IsPlaying=IsPlaying;
}public boolean GetIsPlay() {return IsPlaying;}public void Play(String stramount,boolean strsuccess){String str=null;//如果是TRUE  就播放“收款成功”这句话if (strsuccess){str  =    "$" + PlaySound.capitalValueOf(Double.valueOf(String.format("%.2f", Double.parseDouble(stramount))));
}else {str  = PlaySound.capitalValueOf(Double.valueOf(String.format("%.2f", Double.parseDouble(stramount))));}System.out.println("金额的长度 "+str);String temp ="";try {Thread.sleep(1000);} catch (InterruptedException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}PlaySoundList(1,str,str.length());}public  void PlaySoundList( final int soundindex, final String soundString, final int soundcount){singleton.SetIsPlay(true);boolean createState=false;if(mediaPlayer==null) {mediaPlayer = null;}System.out.println("加载音频["+soundindex+"]");mediaPlayer = createSound(soundindex,soundString);createState=true;if(createState==true)System.out.println("加载音频成功["+soundindex+"]");elseSystem.out.println("加载音频失败["+soundindex+"]");//播放完成触发此事件mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mp) {mp.release();//释放音频资源int newsoundindex =soundindex;System.out.println("释放资源[" +soundindex+"]");if(soundindex<soundcount) {newsoundindex=newsoundindex+1;PlaySoundList(newsoundindex, soundString,soundcount);}else {singleton.SetIsPlay(false);}}});try {//在播放音频资源之前,必须调用Prepare方法完成些准备工作if(createState)mediaPlayer.prepare();elsemediaPlayer.prepare();//开始播放音频mediaPlayer.start();System.out.println("播放音频["+soundindex+"]");} catch (IllegalStateException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}public  MediaPlayer createSound(int soundIndex, String soundString){MediaPlayer mp=null;String soundChar = soundString.substring(soundIndex-1,soundIndex);switch (soundChar){case "零":mp=MediaPlayer.create(mContext,R.raw.sound0);break;case "壹":mp=MediaPlayer.create(mContext,R.raw.sound1);break;case "贰":mp=MediaPlayer.create(mContext,R.raw.sound2);break;case "叁":mp=MediaPlayer.create(mContext,R.raw.sound3);break;case "肆":mp=MediaPlayer.create(mContext,R.raw.sound4);break;case "伍":mp=MediaPlayer.create(mContext,R.raw.sound5);break;case "陆":mp=MediaPlayer.create(mContext,R.raw.sound6);break;case "柒":mp=MediaPlayer.create(mContext,R.raw.sound7);break;case "捌":mp=MediaPlayer.create(mContext,R.raw.sound8);break;case "玖":mp=MediaPlayer.create(mContext,R.raw.sound9);break;case "拾":mp=MediaPlayer.create(mContext,R.raw.soundshi);break;case "佰":mp=MediaPlayer.create(mContext,R.raw.soundbai);break;case "仟":mp=MediaPlayer.create(mContext,R.raw.soundqian);break;case "角":mp=MediaPlayer.create(mContext,R.raw.soundjiao);break;case "分":mp=MediaPlayer.create(mContext,R.raw.soundfen);break;case "元":mp=MediaPlayer.create(mContext,R.raw.soundyuan);break;case "整":mp=MediaPlayer.create(mContext,R.raw.soundzheng);break;case "万":mp=MediaPlayer.create(mContext,R.raw.soundwan);break;case "$":mp=MediaPlayer.create(mContext,R.raw.soundsuccess);break;}//下面这三句是控制语速,但是只适用于Android6.0 以上,以下的就会报错,所以这个功能下次更新时解决
//        PlaybackParams pbp = new PlaybackParams();
//        pbp.setSpeed(1.5F);
//        mp.setPlaybackParams(pbp);mp.stop();return mp;}}

四.使用

Gradle依赖 -
1.最app外层的build.gradle 添加代码:

allprojects {repositories {jcenter()maven { url 'https://jitpack.io' }}
}

2.在app 的build.gradle中添加:

 dependencies {compile 'com.github.javaexception:VoiceAnnouncements:v1.2'}

使用方法 -
1.普通调用:我想强调的是传入的金额最多精确到”分”,还有在调用的时候应该进行try-catch因为如果传入的不是金额,会出现异常的。 如果是true播报语音为”收款成功+收款金额”,如果是false只播报收款金额。

      //普通用法        VoiceUtils.with(this).Play("111",true);

2.防止用户同时接收多条语音造成语音重叠的调用方法:

private synchronized  void Play(final String str) {if (VoiceUtils.with(this).GetIsPlay()){System.out.println("正在播放语音 ");new Thread() {@Overridepublic  void run() {super.run();try {Thread.sleep(100);//休眠0.1秒Play(str);} catch (InterruptedException e) {e.printStackTrace();}/*** 要执行的操作*/}}.start();}else {System.out.println("不冲突");VoiceUtils.with(this).Play(str,true);}}

播报语速的调控问题,现在因为只能支持Android6.0以上的,所以代码我没添加,等解决后一起更新。
如果有什么不清楚的可以加我公众号或者加微信,希望对大家有所帮助。

MediaPlayer实现金额的语音播报功能 1相关推荐

  1. MediaPlayer实现金额的语音播报功能

    推荐阅读: SurfaceView+MediaPlayer封装之路 Android学习资源分享合集(1) 最近写了一个金额的语音播报功能,已封装成依赖库到Github,希望对大家有所帮助. Githu ...

  2. Android实现收款成功金额的语音播报功能(Nice tone)

    推荐文章: Android实现购物车页面及购物车效果(点击动画) Android自定义收银键盘(原创) Github源码下载地址 我的简书地址 Gradle依赖 - 1.最app外层的build.gr ...

  3. APP收款语音播报功能讲解

    一.背景 比起主动扫码能确定收款多少与是否到账,扫二维码支付场景不能直接确认,需要核对客户付款截屏,目前微信.支付宝在扫二维码支付后,均支持收款方自动播报收款到账信息,为了秦丝APP有更好体验,也需要 ...

  4. 一定要了解的小常识:聚合支付有语音播报功能

    在大部分商机都是使用聚合支付收款,他们在营业收款时都十分需要语音播报,这样可以让他们的收款效率大大提高,那么聚合支付有语音播报功能吗?该怎么去开通呢? 聚合支付二维码:从一柜多码到一柜一码 以往,商家 ...

  5. 实现百度地图导航Demo的语音播报功能

    上文中实现了在本地导入百度地图导航Demo,那么在此基础上如何实现导航的语音播报呢? 一.为该应用申请语音播报(也叫注册) http://developer.baidu.com/map/index.p ...

  6. iOS 后台语音播报功能开发过程中的那些坑

      上个版本的开发计划中产品同学建议在我们的商家版App中做后台语音播报功能,在评审的时候我就在想,完全可以通过Push静默推送来实现后台播放音频来实现(后续事实证明,这是个大坑).   关于静默推送 ...

  7. php加入语音播报功能_PHP实现语音播报功能

    大家估计都知道现在很多AI音响能够给你播报天气,叫你起床...甚至能够接受语音指令!所谓的人工智能音响,听起来很高大上,都说PHP是最好的编程语言,今天我就带大家来实现一个语音播报功能!先大体说一个思 ...

  8. 前端实现语音播报功能

    近期接到需求,内容页中的文字要实现语音播报功能,语音生成已经存入数据库 var myAudio = new Audio(); //arr 中存放的是音频数据,数组的大小是不确定的 var arr = ...

  9. html5实现百度语音播报功能

    html5实现百度语音播报功能 总结 记录一下,html5调用百度语音接口实现语音播报功能,简单的完整案例 <!DOCTYPE html> <html> <head> ...

最新文章

  1. 精美的电路图都是怎么画出来的?
  2. html中透明度怎么写,css中控制透明度
  3. mac环境mongodb安装与配置
  4. 调整Tomcat上的参数提高性能[转]
  5. Python 包管理之 poetry
  6. find()matlab,Matlab 之 find()函数
  7. vue横向树结构_vue树形结构的实现
  8. 计算机组装技术的心得与体会,计算机技术心得体会
  9. 3d激光雷达开发(法向量预测)
  10. iOS追踪设备和用户
  11. C语言的图形函数库贴吧,自己写的一个图形库,有点问题.来请教大家了
  12. 模拟CMOS集成电路设计中的电流镜及用Cadence Virtuoso IC617设计并仿真有关电路
  13. MES工程师新手,该怎么学习?学习哪些技术?
  14. 新一代同步控制器和触摸屏组合在压延机上的应用
  15. powerbi python词云图_用Power BI制作词云
  16. Python爬虫入门记录1.0:获取网站某板块首页面资讯文章标题
  17. 水仙花数的实现(python)
  18. 基于单片机波形发生器PCB原理图报告设计资料-基于单片机比赛计时计分电路仿真设计-基于单片机报警器与旋转灯设计-基于单片机八路数据电压采集报警控制系统-基于单片机病房呼叫系统控制系统设计【毕设课设资】
  19. 人啊,除了健康,什么都是浮云
  20. 4.4 测试度量指标体系和质量评估

热门文章

  1. 如何获取access_token以及同步菜单
  2. 压缩包解压密码找回密码
  3. LABVIEW2017下载及详细安装教程(包含DAQmx、Mathscript、安捷伦33XXX等驱动)
  4. appserv2.5.9 php版本,AppServ2.5.9官方下载
  5. 20145312 《信息安全系统设计基础》期中总结
  6. 杭电电子考研经验交流
  7. Windows server DNS服务器配置与管理
  8. 电气与计算机学院院长论坛报告,安徽工业大学电气与信息工程学院院长王兵教授来我校做学术报告...
  9. 腾讯IEG后台开发(已拿到offer)
  10. 龙芯2K1000运行linux,对龙芯2K1000处理器的支持补丁已经合并进Linux 5.