Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android集成訊飛SDK實現語音撥號、語音導航、語音啟動應用

Android集成訊飛SDK實現語音撥號、語音導航、語音啟動應用

編輯:關於Android編程

 

今天來看看對語義分析結果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);
        }
    }
} 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved