# 1. 下載SDK
* * * * *
在[AIUI開放平臺](http://aiui.xfyun.cn)創建完應用后,即可下載對應的SDK包。SDK包里包含MSC與AIUI庫,本文檔僅介紹Android版AIUI庫的入門使用,如需了解MSC庫,請訪問[MSC開發指南](http://doc.xfyun.cn/msc_android/299547)。
# 2. 導入SDK
* * * * *
將下載的Android SDK壓縮包中libs目錄下的libaiui.so以及AIUI.jar拷貝至Android工程的libs目錄下,并將SDK包中assets目錄下cfg文件夾以及res目錄下vad文件夾拷貝至工程中。工程結構如下圖所示:
:-: 
將AIUI.jar添加至工程依賴,將app module下的gradle配置文件中指定默認jniLibs目錄為libs。
~~~
android {
...
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
...
}
~~~
# 3. 添加用戶權限
* * * * *
在工程AndroidManifest.xml文件中添加如下權限
~~~
<!--連接網絡權限,用于執行云端語音能力 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!--獲取手機錄音機使用權限,聽寫、識別、語義理解需要用到此權限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!--讀取網絡信息狀態 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--獲取當前wifi狀態 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--允許程序改變網絡連接狀態 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!--讀取手機信息權限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!--讀取聯系人權限,上傳聯系人需要用到此權限 -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<!--外存儲寫權限,構建語法需要用到此權限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--外存儲讀權限,構建語法需要用到此權限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--配置權限,用來記錄應用配置信息 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<!--手機定位信息,用來為語義等功能提供定位,提供更精準的服務-->
<!--定位信息是敏感信息,可通過Setting.setLocationEnable(false)關閉定位請求 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
~~~
注意:如需在打包或者生成APK的時候進行混淆,請在proguard.cfg中添加如下代碼:
~~~
-keep class com.iflytek.**{*;}
-keepattributes Signature
~~~
# 4. 修改配置
修改cfg/aiui_phone.cfg中的appid信息,將里面的"XXXXXXXX"替換為您自己應用的appid即可。若您下載下來的SDK包已經自動將appid信息打包在cfg文件中了,則可忽略此步驟。
# 5. 創建AIUIAgent
* * * * *
SDK中提供的AIUIAgent就是和AIUI交互的橋梁。先創建`AIUIAgent`,再發送`CMD_START`消息,使AIUI處于工作狀態,示例如下:
~~~
//創建AIUIAgent
AIUIAgent mAIUIAgent = AIUIAgent.createAgent(context,getAIUIParams(),mAIUIListener);
//發送`CMD_START`消息,使AIUI處于工作狀態
AIUIMessage startMsg = new AIUIMessage(AIUIConstant.CMD_START, 0, 0, null, null);
mAIUIAgent.sendMessage( startMsg );
~~~
createAgent 方法包含三個參數:
①第一個參數類型為Context;
②第二個參數類型為String,具體值是通過讀取assets目錄下的cfg/aiui_phone_user.cfg文件而獲得的字符串;
③第三個參數類型為AIUIListener,是AIUI事件回調監聽器。
getAIUIParams()具體示例如下所示:
~~~
private String getAIUIParams() {
String params = "";
AssetManager assetManager = getResources().getAssets();
try {
InputStream ins = assetManager.open( "cfg/aiui_phone.cfg" );
byte[] buffer = new byte[ins.available()];
ins.read(buffer);
ins.close();
params = new String(buffer);
} catch (IOException e) {
e.printStackTrace();
}
return params;
}
}
~~~
mAIUIListener具體示例如下所示:
~~~
AIUIListener mAIUIListener = new AIUIListener() {
@Override
public void onEvent(AIUIEvent event) {
switch (event.eventType) {
//喚醒事件
case AIUIConstant.EVENT_WAKEUP:
{
break;
}
//結果事件(包含聽寫,語義,離線語法結果)
case AIUIConstant.EVENT_RESULT:
{
break;
}
//休眠事件
case AIUIConstant.EVENT_SLEEP:
{
break;
}
// 狀態事件
case AIUIConstant.EVENT_STATE: {
mAIUIState = event.arg1;
if (AIUIConstant.STATE_IDLE == mAIUIState) {
// 閑置狀態,AIUI未開啟
} else if (AIUIConstant.STATE_READY == mAIUIState) {
// AIUI已就緒,等待喚醒
} else if (AIUIConstant.STATE_WORKING == mAIUIState) {
// AIUI工作中,可進行交互
}
} break;
//錯誤事件
case AIUIConstant.EVENT_ERROR:
{
break;
}
}
}
~~~
# 6. 文本語義理解示例
* * * * *
發送CMD_WAKEUP消息至AIUI,使AIUI處于喚醒狀態,再通過構造`CMD_WRITE`消息,將要進行語義理解的文本數據發送給AIUI,并通過AIUIListener的回調,獲取語義結果。代碼示例如下:
~~~
// 先發送喚醒消息,改變AIUI內部狀態,只有喚醒狀態才能接收語音輸入
if( AIUIConstant.STATE_WORKING != mAIUIState ){
AIUIMessage wakeupMsg = new AIUIMessage(AIUIConstant.CMD_WAKEUP, 0, 0, "", null);
mAIUIAgent.sendMessage(wakeupMsg);
}
AIUIMessage msg = new AIUIMessage(AIUIConstant.CMD_WRITE, 0, 0, "data_type=text", "今天天氣怎么樣".getBytes());
mAIUIAgent.sendMessage(msg);
~~~
其中mAIUIState代表當前AIUI狀態,當AIUI狀態改變時,會在mAIUIListener中拋出EVENT_STATE事件,可通過其獲取AIUI狀態。
# 7. 語音語義理解示例
* * * * *
發送CMD_WAKEUP消息至AIUI,使AIUI處于喚醒狀態,再發送開始錄音消息,使麥克風錄入音頻,并通過AIUIListener的回調,獲取語義結果。代碼示例如下:
~~~
// 先發送喚醒消息,改變AIUI內部狀態,只有喚醒狀態才能接收語音輸入
if( AIUIConstant.STATE_WORKING != mAIUIState ){
AIUIMessage wakeupMsg = new AIUIMessage(AIUIConstant.CMD_WAKEUP, 0, 0, "", null);
mAIUIAgent.sendMessage(wakeupMsg);
}
// 打開AIUI內部錄音機,開始錄音
String params = "sample_rate=16000,data_type=audio";
AIUIMessage writeMsg = new AIUIMessage( AIUIConstant.CMD_START_RECORD, 0, 0, params, null );
mAIUIAgent.sendMessage(writeMsg);
~~~
如出現20006錯誤,請注意下應用是否擁有錄音權限。返回的語義結果,參考[語義結果說明文檔](http://aiui.xfyun.cn/help/devDoc#4)
# 8. 結果解析
* * * * *
在AIUIEventListener回調中,可以收到來自AIUI的多種消息,具體示例如下:
~~~
private AIUIListener mAIUIListener = new AIUIListener() {
@Override
public void onEvent(AIUIEvent event) {
switch (event.eventType) {
case AIUIConstant.EVENT_WAKEUP:
//喚醒事件
Log.i( TAG, "on event: "+ event.eventType );
break;
case AIUIConstant.EVENT_RESULT: {
//結果解析事件
try {
JSONObject bizParamJson = new JSONObject(event.info);
JSONObject data = bizParamJson.getJSONArray("data").getJSONObject(0);
JSONObject params = data.getJSONObject("params");
JSONObject content = data.getJSONArray("content").getJSONObject(0);
if (content.has("cnt_id")) {
String cnt_id = content.getString("cnt_id");
JSONObject cntJson = new JSONObject(new String(event.data.getByteArray(cnt_id), "utf-8"));
String sub = params.optString("sub");
if ("nlp".equals(sub)) {
// 解析得到語義結果
String resultStr = cntJson.optString("intent");
Log.i( TAG, resultStr );
}
}
} catch (Throwable e) {
e.printStackTrace();
}
} break;
case AIUIConstant.EVENT_ERROR: {
//錯誤事件
Log.i( TAG, "on event: "+ event.eventType );
Log.e(TAG, "錯誤: "+event.arg1+"\n"+event.info );
} break;
case AIUIConstant.EVENT_VAD: {
if (AIUIConstant.VAD_BOS == event.arg1) {
//語音前端點
} else if (AIUIConstant.VAD_EOS == event.arg1) {
//語音后端點
}
} break;
case AIUIConstant.EVENT_START_RECORD: {
Log.i( TAG, "on event: "+ event.eventType );
//開始錄音
} break;
case AIUIConstant.EVENT_STOP_RECORD: {
Log.i( TAG, "on event: "+ event.eventType );
// 停止錄音
} break;
case AIUIConstant.EVENT_STATE: { // 狀態事件
mAIUIState = event.arg1;
if (AIUIConstant.STATE_IDLE == mAIUIState) {
// 閑置狀態,AIUI未開啟
} else if (AIUIConstant.STATE_READY == mAIUIState) {
// AIUI已就緒,等待喚醒
} else if (AIUIConstant.STATE_WORKING == mAIUIState) {
// AIUI工作中,可進行交互
}
} break;
default:
break;
}
}
};
~~~