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

转载请注明出处:周木水的CSDN博客

http://blog.csdn.net/zhoumushui

科大讯飞语音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.setOnGetGeoCodeResultListener(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 = "到这里结束";

                try {
                    BaiduMapNavigation.openBaiduMapNavi(para,
                            getApplicationContext());
                } catch (BaiduMapAppNotSupportNaviException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
        }
    }

语音启动应用



当我们说”打开百度地图“时,服务器返回的JSON是:

{
"semantic": {
"slots": {
"name": "百度地图"
}
},
"rc": 0,
"operation": "LAUNCH",
"service": "app",
"text": "打开百度地图。"
}

和语音拨号类似,我们可以获取到应用的名称,然后和ResolveInfo中应用的名称Label进行比对,如果匹配,则拿到包名,然后进行启动。

注意:要考虑到应用名称为非中文的情况。(比如我们说”启动QQ“,但讯飞识别的是”qq“,如果简单粗暴的进行String的equals比较,则会匹配失败。这时候需要将应用名称与Label都转成大写或小写。)

if ("app".equals(strService)) {
    // "operation": "LAUNCH",
    String appName = jsonObject.getJSONObject("semantic").getJSONObject("slots").getString("name");
    String operationStr = jsonObject.getString("operation");
    if ("LAUNCH".equals(operationStr)) {
        String packageName = getAppPackageByName(appName);
        Toast.makeText(getApplicationContext(),packageName, Toast.LENGTH_SHORT).show();
        if (!"com.tchip.carlauncher".equals(packageName)) {
            String strAnswer = "正在启动:"+ appName;
            tvAnswer.setText(strAnswer);
            startSpeak(strAnswer);
            startAppbyPackage(packageName);
        } else {
            String strAnswer = "未找到应用:"+ appName;
            tvAnswer.setText(strAnswer);
            startSpeak(strAnswer);
        }
    }
} 

转载请注明出处:周木水的CSDN博客

http://blog.csdn.net/zhoumushui

时间: 2024-12-28 06:20:59

Android集成讯飞SDK实现语音拨号、语音导航、语音启动应用的相关文章

Android Studio快速集成讯飞SDK实现文字朗读功能

今天,我们来学习一下怎么在Android Studio快速集成讯飞SDK实现文字朗读功能,先看一下效果图: 第一步 :了解TTS语音服务 TTS的全称为Text To Speech,即“从文本到语音”.它是同时运用语言学和心理学的杰出之作,在内置芯片的支持之下,通过神经网络的设计,把文字智能地转化为自然语音流. TTS技术对文本文件进行实时转换,转换时间之短可以秒计算.在其特有智能语音控制器作用下,文本输出的语音音律流畅,使得听者在听取信息时感觉自然,毫无机器语音输出的冷漠与生涩感.使用户可以听

Android集成讯飞语音、百度语音、阿里语音识别

项目实践:https://blog.csdn.net/Jsagacity/article/details/80094164 demo下载地址:https://fir.im/jy28 demo源码:https://github.com/wapchief/android-CollectionDemo 百度网盘:https://pan.baidu.com/s/1gvoTlcddstxb7tyS8MvWzw密码:l5gd 2 科大讯飞  https://www.xfyun.cn/ 网友使用1https:

Android 使用讯飞语音SDK

最近一直忙着写代码,每天的空闲时间不多.先占位,慢慢填坑. 讯飞开放平台: http://www.xfyun.cn/ 注册为开发者,然后参照文档一步步走下去. 由于是商业SDK,平台有诸多限制,免费的话只能联网,并且有限制次数,应用通过审核后无请求次数限制.

android用讯飞实现TTS语音合成 实现中文版

Android系统从1.6版本开始就支持TTS(Text-To-Speech),即语音合成.但是android系统默认的TTS引擎:Pic TTS不支持中文.所以我们得安装自己的TTS引擎和语音包. 在项目中,一开始用的是手说TTS,免费版的,感觉声音很不僵硬,不自然,不连贯.付费版的还要钱激活,如果不激活,限制每次只能度5个字,而且比免费版也好不了多少.最后采用了讯飞语音TTS1.0,发音连贯自然,个人感觉很不错了,以后就用它. 介绍下使用方法: 1.首先下载讯飞的语音包apk,以及语音引擎a

(转)IOS App中揉合讯飞SDK功能详细

转至:http://www.sufeinet.com/thread-2488-1-1.html 如何使用讯飞的语音SDK加入到你的iPhone应用中吧!1.首先请先到讯飞官方网站的开发者专区(http://open.voicecloud.cn/developer.php).如果你还没有注册,那么需要先注册一个开发者账号的.点击网站顶部的"免费注册"即可,使用你的自己的手机号码注册一个账号.2.仅仅注册了一个开发者账号还可以使用SDK,因为还需要申请Appid.登陆之后到自己的个人中心创

android 使用讯飞人脸识别api报错:java.lang.UnsatisfiedLinkError

1.在做一个人脸识别的项目,使用的是讯飞的api,编辑器为AS2.0,运行时报如下错误: FATAL EXCEPTION: main                  Process: com.admin.smartcam, PID: 13821                  java.lang.UnsatisfiedLinkError: Native method not found: com.faceplusplus.api.Native.setMinFaceSize:(II)I    

集成讯飞语音

http://blog.csdn.net/u012635169/article/details/51049752 这个帖子非常简单但需要添加权限 <!--连接网络权限,用于执行云端语音能力 --> <uses-permission android:name="android.permission.INTERNET" /> <!--获取手机录音机使用权限,听写.识别.语义理解需要用到此权限 --> <uses-permission android

android 开发 讯飞语音唤醒功能

场景:进入程序后处于语音唤醒状态,当说到某个关键词的时候打开某个子界面(如:语音识别界面) 技术要点: 1. // 设置唤醒一直保持,直到调用stopListening,传入0则完成一次唤醒后,会话立即结束(默认0) mIvw.setParameter(SpeechConstant.KEEP_ALIVE, "1"); 2.添加资源文件appid.jet    很奇怪为什么这里demo里面不需要语法文件 关键代码: /*********************************语音

UNITY 接讯飞语音过程总结

11:13 2017/3/141,安装问题:JDK与ECLIPSE位数一定要对应,32位对64位会出现 java was returned ....code 13的弹框错误.版本号可以不一致.2,ECLIPSE 启动后,需要设置JRE路径,否则代码提示错误.3,智能提示问题:在window -preference -java -editor下设置 .为 .abcdefghijklmnopqrstuvwxyz 17:05 2017/3/17讯飞SDK接入UNITY过程:1,导入unity的类包cl