Android integrates the xunfei SDK to implement voice dialing, voice navigation, and voice startup applications
Let's take a look at the parsing and processing of the semantic analysis result JSON:
Voice Dialing
First, let's take a look at the JSON that is sent to us after the server analysis:
{Semantic: {slots: {name: James }}, rc: 0, operation: CALL, service: telephone, text: CALL Michael .}
Therefore, our idea is to get the name, and then match the DisplayName of the contact in the contact ContentProvider one by one. However, we need to consider the homophone problem (for example, "call Zhang Xiaojing" and the name returned by the server is "Zhang Xiaojing", which cannot be matched .) If no match exists, convert the name to pinyin, and then compare it with the contact pinyin.
Let's take a look at the core code:
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 = is calling: + 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 = is calling: + 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 = is calling: + 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 = address book not found: + peopleName; tvAnswer. setText (strAnswer); startSpeak (strAnswer );}}}}
Voice Navigation
Here, we do not consider the situation where "how to go from A to B (both A and B are remote. The parsing method is the same when the starting point is not the current position, but it is not commonly used. Therefore, the starting point of the example here is the current location by default.
When we say "navigate to Shenzhen North Station", the server returns the following JSON:
{Semantic: {slots: {endLoc: {type: LOC_POI, poi: Shenzhen South Station, city: Shenzhen, cityAddr: Shenzhen}, startLoc: {type: LOC_POI, city: CURRENT_CITY, poi: CURRENT_POI }}, rc: 0, operation: ROUTE, service: map, text: navigate to Shenzhen South Railway Station .}
First, parse 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, unknown );}
To call the navigation interface of Baidu map, you need to input the longitude and latitude of the start point. The longitude and latitude of the current location are known, so you need to convert the string of the destination to the latitude and longitude. This involves the use of Baidu lbs sdk:
{ mEndSearch = GeoCoder.newInstance(); mEndSearch.setOnGetGeoCodeResultListener(new MyOnGetGeoCoderResultListener()); mEndSearch.geocode(new GeoCodeOption().city(endCityStr).address(endPoiStr)); }
Class implements OnGetGeoCoderResultListener {@ Override public void onGetGeoCodeResult (GeoCodeResult result) {// TODO Auto-generated method stub mEndLatLng = result. getLocation (); if (mEndLatLng! = Null) {// start point: Current Position startLat = Double. parseDouble (mSharedPreferences. getString (latitude, 0.0); startLng = Double. parseDouble (mSharedPreferences. getString (longpolling, 0.0); // destination endLat = mEndLatLng. latitude; endLng = mEndLatLng. longpolling; LatLng startLatLng = new LatLng (startLat, startLng); LatLng endLatLng = new LatLng (endLat, endLng); // construct the navigation parameter NaviPara para = new NaviPara (); para. startPoint = startLatLng; para. startName = start from here; para. endPoint = endLatLng; para. endName = ends here; try {BaiduMapNavigation. openBaiduMapNavi (para, getApplicationContext ();} catch (BaiduMapAppNotSupportNaviException e) {e. printStackTrace () ;}}@ Override public void onGetReverseGeoCodeResult (ReverseGeoCodeResult result ){}}
Enable Application
When we say "open Baidu map", the server returns the following JSON:
{Semantic: {slots: {name: Baidu map}, rc: 0, operation: LAUNCH, service: app, text: Open Baidu map .}
Similar to voice dialing, we can get the name of the application and compare it with the name Label of the application in ResolveInfo. If yes, we get the package name and start it.
Note: The application name must be non-Chinese. (For example, we say "Start QQ", but xunfei recognizes "qq". If the String equals is compared roughly, the matching will fail. In this case, both the application name and Label must be converted to uppercase or lowercase letters .)
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 = starting: + appName; tvAnswer. setText (strAnswer); startSpeak (strAnswer); startAppbyPackage (packageName);} else {String strAnswer = application not found: + appName; tvAnswer. setText (strAnswer); startSpeak (strAnswer );}}}