写点什么

Android 集成讯飞 SDK 实现语音拨号、语音导航、语音启动应用

用户头像
Android架构
关注
发布于: 1 小时前

科大讯飞语音 SDK 的语义分析还是挺强大的,可使我们的应用更加强大。


上篇博文介绍了讯飞 SDK 的一些简单功能:


Android 使用讯飞语音SDK


今天来看看对语义分析结果 JSON 的解析并处理:


实现语音拨号






首先,我们看看“打电话给张三”这句话在服务器分析之后,传给我们的 JSON 是什么样的:


{


"semantic": {


"slots": {


"name": "张三"


}


},


"rc": 0,


"operation": "CALL",


"service": "telephone",


"text": "打电话给张三。"


}


所以,我们的思路就是获取到 name,然后和联系人 ContentProvider 中的联系人 DisplayName 进行逐一匹配。但是要考虑到同音字的问题(例如:“打电话给张晓静”,服务器返回的 name 是”张小静“,这就没法匹配。)在没有匹配的情况下,我们将 name 转成拼音,然后再和联系人拼音进行对比即可。


看一下核心代码:


if ("telephone".equals(strService)) {


// "operation": "CALL"


String peopleName = jsonObject.getJSONObject("semantic").getJSONObject("slots").getString("name");


String operationStr = jsonObject.getString("operation");


if ("CALL".equals(operationStr)) {


String phoneNum = getContactNumberByName(peopleName);


String phoneCode = "";


try {


phoneCode = jsonObject.getJSONObject("semantic").getJSONObject("slots").getString("code");


} catch (Exception e) {}


if (phoneNum != null & phoneNum.trim().length() > 0) {


String strAnswer = "正在打电话给:" + peopleName;


tvAnswer.setText(strAnswer);


startSpeak(strAnswer);


Uri uri = Uri.parse("tel:" + phoneNum);


Intent intent = new Intent(Intent.ACTION_CALL, uri);


startActivity(intent);


} else if (phoneCode != null& phoneCode.trim().length() > 0) {


String strAnswer = "正在打电话给:" + peopleName;


tvAnswer.setText(strAnswer);


startSpeak(strAnswer);


Uri uri = Uri.parse("tel:" + phoneCode);


Intent intent = new Intent(Intent.ACTION_CALL, uri);


startActivity(intent);


} else {


String phoneNumFromPinYin = getContactNumberByPinYin(PinYinUtil.convertAll(peopleName));


if (phoneNumFromPinYin != null& phoneNumFromPinYin.trim().length() > 0) {


String strAnswer = "正在打电话给:" + peopleName;


tvAnswer.setText(strAnswer);


startSpeak(strAnswer);


Uri uri = Uri.parse("tel:" + phoneNumFromPinYin);


Intent intent = new Intent(Intent.ACTION_CALL, uri);


startActivity(intent);


} else {


String strAnswer = "通讯录中未找到:" + peopleName;


tvAnswer.setText(strAnswer);


startSpeak(strAnswer);


}


}


}


}


语音导航






这里不考虑”从 A 到 B 怎么走(A,B 都为异地)“的情况。起点不是当前位置的情况解析方式相同,只是不常用。所以这里的例子起点默认为当前定位位置。


当我们说”导航到深圳北站“时,服务器返回的 JSON 如下:


{


"semantic": {


"slots": {


"endLoc": {


"type": "LOC_POI",


"poi": "深圳南站",


"city": "深圳市",


"cityAddr": "深圳"


},


"startLoc": {


"type": "LOC_POI",


"city": "CURRENT_CITY",


"poi": "CURRENT_POI"


}


}


},


"rc": 0,


"operation": "ROUTE",


"service": "map",


"text": "导航到深圳南站。"


}


首先我们对 JSON 进行解析:


if ("map".equals(strService)) {


// operation": "ROUTE"


String endPoiStr = jsonObject.getJSONObject("semantic").getJSONObject("slots").getJSONObject("endLoc").getString("poi");


String endCityStr = jsonObject.getJSONObject("semantic").getJSONObject("slots").getJSONObject("endLoc").getString("city");


String endAddressStr = "";


if ("CURRENT_CITY".equals(endCityStr))


endCityStr = mSharedPreferences.getString("cityName", "未知");


}


调用百度地图的导航接口,需要传入起始点的经纬度。当前位置的经纬度是已知的,所以要将目的地的字符串转成经纬度。这就涉及到百度 LBS SDK 的使用:


{


mEndSearch = GeoCoder.newInstance();


mEndSearch.setOnGetGeoCodeResultListe


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


ner(new MyOnGetGeoCoderResultListener());


mEndSearch.geocode(new GeoCodeOption().city(endCityStr).address(endPoiStr));


}


class MyOnGetGeoCoderResultListener implements OnGetGeoCoderResultListener {


@Override


public void onGetGeoCodeResult(GeoCodeResult result) {


// TODO Auto-generated method stub


mEndLatLng = result.getLocation();


if (mEndLatLng != null) {


// 起始点:当前位置


startLat = Double.parseDouble(mSharedPreferences.getString(


"latitude", "0.0"));


startLng = Double.parseDouble(mSharedPreferences.getString(


"longitude", "0.0"));


// 目的地


endLat = mEndLatLng.latitude;


endLng = mEndLatLng.longitude;


LatLng startLatLng = new LatLng(startLat, startLng);


LatLng endLatLng = new LatLng(endLat, endLng);


// 构建 导航参数


NaviPara para = new NaviPara();


para.startPoint = startLatLng;


para.startName = "从这里开始";


para.endPoint = endLatLng;


para.endName = "到这里结束";

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android 集成讯飞SDK实现语音拨号、语音导航、语音启动应用