TextTranslatorOpenSource-文本翻譯器開源版
僅用于學(xué)習(xí)研究之用纲缓,請(qǐng)勿商用
介紹
【文本翻譯器】是一款免費(fèi)的簡(jiǎn)潔實(shí)用的翻譯軟件募胃。文本翻譯器應(yīng)用程序完全免費(fèi)驾荣,可以非城垂快速翻譯您的單詞框喳,幫助您與外國(guó)人交流唇兑。文本翻譯器適用于旅行者坎弯、學(xué)生纺涤、商人和其他語(yǔ)言愛好者,使用文本翻譯器可以輕松了解其他語(yǔ)言抠忘。文本翻譯器支持多國(guó)語(yǔ)言撩炊,全新領(lǐng)先的翻譯引擎,讓各種變得更加可靠有保證崎脉。界面設(shè)計(jì)簡(jiǎn)潔衰抑、優(yōu)雅,體積小巧荧嵌,但是功能很強(qiáng)大哦呛踊。趕快下載來(lái)試試吧~
功能特點(diǎn):
*【詞典解析】除了基本的翻譯外砾淌,提供更詳細(xì)的詞典功能,詞性分類
*【多語(yǔ)言】目前支持主流語(yǔ)言:中文谭网,中文繁體汪厨,英語(yǔ),日語(yǔ)愉择,法語(yǔ)劫乱,德語(yǔ)
*【單詞本】收藏喜歡的單詞
*【歷史記錄】記錄翻譯記錄
*【離線翻譯】如果已經(jīng)翻譯過(guò)的即使沒(méi)有網(wǎng)絡(luò)也能翻譯
*【數(shù)據(jù)備份和恢復(fù)】備份歷史翻譯記錄和恢復(fù)記錄
*【自動(dòng)朗讀】翻譯后為您朗讀
*【自動(dòng)復(fù)制】將翻譯文本自動(dòng)復(fù)制到剪貼板
*【全局復(fù)制查詞】在任何界面點(diǎn)復(fù)制就能查單詞
*【免費(fèi)】使用功能過(guò)程中完全免費(fèi)
*【界面簡(jiǎn)潔】界面設(shè)計(jì)優(yōu)雅、簡(jiǎn)潔
展示
下載
Google Play
https://play.google.com/store/apps/details?id=com.allever.app.translation.text
Baidu
https://shouji.baidu.com/software/26838949.html
項(xiàng)目地址
https://github.com/devallever/TranslationTextOpenSource
項(xiàng)目架構(gòu)
項(xiàng)目采用多組件 + MVP 架構(gòu)
項(xiàng)目組件架構(gòu)圖
- common:通用模塊衷戈,包括基類和通用工具類,基本上所有模塊都依賴此模塊
- commont:評(píng)分模塊
- permission:申請(qǐng)權(quán)限模塊
- recomend:推廣模塊
- umeng:友盟統(tǒng)計(jì)
- widget:通用UI組件模塊
項(xiàng)目包圖
- app:基類和全局類
- bean:實(shí)體類和EventBus事件類
- function:功能類
- ui:界面层坠,包括mvp
- util:工具類
其中主要代碼是在ui和function這兩個(gè)包
如何使用
- 項(xiàng)目需要依賴AndroidDependencyLib中的一個(gè)或多個(gè)模塊殖妇,請(qǐng)預(yù)先配置
把AndroidDependencyLib項(xiàng)目和本項(xiàng)目放同一個(gè)目錄下
項(xiàng)目需要依賴AndroidUIKit中的一個(gè)或多個(gè)模塊,請(qǐng)預(yù)先配置
接口
翻譯接口
可以參考以下默認(rèn)值
@GET("translate_a/single")
fun translate(
@Query("q") q: String,
@Query("client") content: String = "gtx",
@Query("dt") dt: String = "t",
@Query("dt") dt1: String = "bd",
@Query("dt") dt2: String = "rm",
@Query("dj") dj: String = "1",
@Query("ie") ie: String = "UTF-8",
@Query("oe") oe: String = "UTF-8",
@Query("sl") sl: String = "auto",
@Query("tl") tl: String = "en",
@Query("hl") hl: String = "zh-CN",
@Query("tk") tk: String = ""
): Observable<TranslationBean>
主要用到sl破花、tl和q這幾個(gè)參數(shù)
- sl:原語(yǔ)種
- tl:翻譯語(yǔ)種
- q:翻譯文本
關(guān)于語(yǔ)種可以參考項(xiàng)目中Languages這個(gè)類伞租,包含了100多個(gè)語(yǔ)種代碼
- Languages
返回json對(duì)應(yīng)TranslationBean.kt這個(gè)實(shí)體類
/***
* {"sentences":[{"trans":"串","orig":"string","backend":2},{"translit":"Chuàn","src_translit":"striNG"}],"dict":[{"pos":"名詞","terms":["串","弦","線","繩","繩子","細(xì)線","鞭","緄"],"entry":[{"word":"串","reverse_translation":["string"],"score":0.13323711},{"word":"弦","reverse_translation":["string","chord","bowstring","hypotenuse","subtense","string of musical instrument"],"score":0.016418032},{"word":"線","reverse_translation":["line","wire","thread","string","route","filament"],"score":0.0058540297},{"word":"繩","reverse_translation":["rope","cord","string"],"score":0.00477792},{"word":"繩子","reverse_translation":["rope","string","cord"],"score":0.0023652418},{"word":"細(xì)線","reverse_translation":["thread","string"],"score":2.2698537E-4},{"word":"鞭","reverse_translation":["whip","lash","string","firecracker","iron staff used as a weapon"],"score":8.139759E-6},{"word":"緄","reverse_translation":["cord","embroidered sash","string"],"score":2.4439987E-6}],"base_form":"string","pos_enum":1},{"pos":"動(dòng)詞","terms":["紉"],"entry":[{"word":"紉","reverse_translation":["thread","string"],"score":4.860472E-6}],"base_form":"string","pos_enum":2}],"src":"en","confidence":0.9488189,"ld_result":{"srclangs":["en"],"srclangs_confidences":[0.9488189],"extended_srclangs":["en"]}}
*/
@Keep
class TranslationBean {
/**
* sentences : [{"trans":"串","orig":"string","backend":2},{"translit":"Chuàn","src_translit":"striNG"}]
* dict : [{"pos":"名詞","terms":["串","弦","線","繩","繩子","細(xì)線","鞭","緄"],"entry":[{"word":"串","reverse_translation":["string"],"score":0.13323711},{"word":"弦","reverse_translation":["string","chord","bowstring","hypotenuse","subtense","string of musical instrument"],"score":0.016418032},{"word":"線","reverse_translation":["line","wire","thread","string","route","filament"],"score":0.0058540297},{"word":"繩","reverse_translation":["rope","cord","string"],"score":0.00477792},{"word":"繩子","reverse_translation":["rope","string","cord"],"score":0.0023652418},{"word":"細(xì)線","reverse_translation":["thread","string"],"score":2.2698537E-4},{"word":"鞭","reverse_translation":["whip","lash","string","firecracker","iron staff used as a weapon"],"score":8.139759E-6},{"word":"緄","reverse_translation":["cord","embroidered sash","string"],"score":2.4439987E-6}],"base_form":"string","pos_enum":1},{"pos":"動(dòng)詞","terms":["紉"],"entry":[{"word":"紉","reverse_translation":["thread","string"],"score":4.860472E-6}],"base_form":"string","pos_enum":2}]
* src : en
* confidence : 0.9488189
* ld_result : {"srclangs":["en"],"srclangs_confidences":[0.9488189],"extended_srclangs":["en"]}
*/
var src: String? = null
var confidence: Double = 0.toDouble()
var ld_result: LdResultBean? = null
var sentences: List<SentencesBean>? = null
var dict: List<DictBean>? = null
@Keep
class LdResultBean {
var srclangs: List<String>? = null
var srclangs_confidences: List<Double>? = null
var extended_srclangs: List<String>? = null
}
@Keep
class SentencesBean {
/**
* trans : 串
* orig : string
* backend : 2
* translit : Chuàn
* src_translit : striNG
*/
var trans: String? = null
var orig: String? = null
var backend: Int = 0
var translit: String? = null
var src_translit: String? = null
}
@Keep
class DictBean {
/**
* pos : 名詞
* terms : ["串","弦","線","繩","繩子","細(xì)線","鞭","緄"]
* entry : [{"word":"串","reverse_translation":["string"],"score":0.13323711},{"word":"弦","reverse_translation":["string","chord","bowstring","hypotenuse","subtense","string of musical instrument"],"score":0.016418032},{"word":"線","reverse_translation":["line","wire","thread","string","route","filament"],"score":0.0058540297},{"word":"繩","reverse_translation":["rope","cord","string"],"score":0.00477792},{"word":"繩子","reverse_translation":["rope","string","cord"],"score":0.0023652418},{"word":"細(xì)線","reverse_translation":["thread","string"],"score":2.2698537E-4},{"word":"鞭","reverse_translation":["whip","lash","string","firecracker","iron staff used as a weapon"],"score":8.139759E-6},{"word":"緄","reverse_translation":["cord","embroidered sash","string"],"score":2.4439987E-6}]
* base_form : string
* pos_enum : 1
*/
var pos: String? = null
var base_form: String? = null
var pos_enum: Int = 0
var terms: List<String>? = null
var entry: List<EntryBean>? = null
@Keep
class EntryBean {
/**
* word : 串
* reverse_translation : ["string"]
* score : 0.13323711
*/
var word: String? = null
var score: Double = 0.toDouble()
var reverse_translation: List<String>? = null
}
}
}
- sentences 字段含原文本和翻譯文本
- dict 字段包含詞典信息
- 解析獲取對(duì)應(yīng)字段的內(nèi)容在 TranslationHelper 中
語(yǔ)音接口
其中主要用到 tl 和 q 參數(shù)休里,同上
可以參考以下默認(rèn)值
@GET("translate_tts")
fun requestTTS(
@Query("q") q: String,
@Query("client") content: String = "gtx",
@Query("ie") ie: String = "UTF-8",
@Query("tl") tl: String = "en",
@Query("hl") hl: String = "zh-CN",
@Query("total") total: String = "1",
@Query("idx") idx: String = "0",
@Query("textlen") textlen: String = "0",
@Query("tk") tk: String = ""
): Call<ResponseBody>
翻譯基本流程
項(xiàng)目采用MVP架構(gòu)
- TranslationFragment:調(diào)用presenter接口進(jìn)行請(qǐng)求翻譯
mPresenter.translate(content, sl, tl)
- TranslationPresenter:調(diào)用RetrofitUtil進(jìn)行網(wǎng)絡(luò)請(qǐng)求逆屡,并回調(diào)TranslationView的接口刷新界面
- DBHelper:負(fù)責(zé)存取翻譯記錄
fun translate(content: String, sl: String = Lang.AUTO.CODE, translateLanguage: String) {
if (content.isEmpty()) {
toast(R.string.please_input_content)
return
}
val history = DBHelper.getHistory(content, sl, translateLanguage)
val translationBean =
JsonHelper.json2Object(history?.result ?: "", TranslationBean::class.java)
if (translationBean != null) {
parse(translationBean)
mViewRef?.get()?.refreshLiked(history?.liked == 1)
val translateText = TranslationHelper.getTranslateText(translationBean)
if (translateText.isNotEmpty()) {
play(translateText, translateLanguage)
copyToClipBoard(translateText)
}
log("獲取到數(shù)據(jù)庫(kù)翻譯內(nèi)容")
DBHelper.updateHistoryTime(history)
EventBus.getDefault().post(UpdateRecordEvent())
return
}
RetrofitUtil.translate(object : Subscriber<TranslationBean>() {
override fun onCompleted() {}
override fun onError(e: Throwable) {
e.printStackTrace()
log("失敗")
}
override fun onNext(bean: TranslationBean) {
parse(bean)
val translateText = TranslationHelper.getTranslateText(bean)
mViewRef?.get()?.refreshLiked(false)
play(translateText, translateLanguage)
copyToClipBoard(translateText)
DBHelper.addHistory(content, sl, translateLanguage, bean)
EventBus.getDefault().post(UpdateRecordEvent())
}
}, content, sl, translateLanguage)
}
- TranslationHelper:負(fù)責(zé)解析數(shù)據(jù)
- TranslationView:刷新界面
private fun parse(bean: TranslationBean) {
val srcSymbol = TranslationHelper.getSrcSymbol(bean)
val translateSymbol = TranslationHelper.getTranslateSymbol(bean)
//音標(biāo)顯示邏輯
if (srcSymbol.isNotEmpty()) {
mViewRef?.get()?.showOrHideSoundSrcSymbol(true)
} else {
mViewRef?.get()?.showOrHideSoundSrcSymbol(false)
}
if (translateSymbol.isNotEmpty()) {
mViewRef?.get()?.showOrHideSoundTranslateSymbol(true)
} else {
mViewRef?.get()?.showOrHideSoundTranslateSymbol(false)
}
if (TranslationHelper.getDictText(bean).isNotEmpty()) {
mViewRef?.get()?.showOrHideDictInfo(true)
} else {
mViewRef?.get()?.showOrHideDictInfo(false)
}
mViewRef?.get()?.updateResult(
bean,
TranslationHelper.getSrcLang(bean),
TranslationHelper.getSrcText(bean),
TranslationHelper.getSrcSymbol(bean),
TranslationHelper.getTranslateText(bean),
TranslationHelper.getTranslateSymbol(bean),
TranslationHelper.getDictText(bean)
)
}
以上就是翻譯的基本流程
復(fù)制查詞功能實(shí)現(xiàn)
- 監(jiān)聽粘貼板變化并彈出Dialog風(fēng)格的Activity高诺,當(dāng)在應(yīng)用內(nèi)復(fù)制時(shí)候,不彈出峭梳。
val clipBoardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
clipBoardManager.addPrimaryClipChangedListener {
log("剪貼板變化")
if (ActivityCollector.size() == 0 && SettingHelper.getAutoTranslate()) {
val srcText = clipBoardManager.primaryClip?.getItemAt(0)?.text.toString()
DialogTranslateActivity.start(this, srcText)
}
}
通知欄常駐
- 啟動(dòng)一個(gè)前臺(tái)服務(wù) TranslationService 苯⒒妫活
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
log("啟動(dòng)服務(wù)")
val paddingFlag = 1
val pendingIntent = PendingIntent.getActivity(
this,
0,
Intent(this, MainDrawerActivity::class.java),
PendingIntent.FLAG_UPDATE_CURRENT,
null
)
val notificationBuilder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channelId = "translation"
val channelName = "翻譯"
val importance = NotificationManager.IMPORTANCE_HIGH
createNotificationChannel(channelId, channelName, importance)
NotificationCompat.Builder(this, channelId)
.setNumber(paddingFlag)
} else {
NotificationCompat.Builder(this)
}
notificationBuilder
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.notification_msg, getString(R.string.app_name)))
.setSmallIcon(R.drawable.ic_logo)
.setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.ic_logo))
.setContentIntent(pendingIntent)
startForeground(1, notificationBuilder.build())
return super.onStartCommand(intent, flags, startId)
}
離線翻譯功能
將翻譯過(guò)的記錄保存下來(lái),即每次請(qǐng)求網(wǎng)絡(luò)翻譯時(shí)候就保存記錄
//sl:原語(yǔ)種代碼
//translateLanguage:翻譯語(yǔ)種代碼
//bean:TranslationBean請(qǐng)求翻譯的實(shí)體類
DBHelper.addHistory(content, sl, translateLanguage, bean)
通過(guò)History這個(gè)實(shí)體類保存翻譯記錄
fun addHistory(content: String, sl: String, tl: String, bean: TranslationBean) {
run {
try {
val history = History()
history.srcText = content
history.sl = sl
history.tl = tl
history.time = System.currentTimeMillis()
history.liked = 0
history.result = Gson().toJson(bean)
history.ttsPath = MD5.getMD5StrToLowerCase("$content$tl.mp3")
val saveResult = history.save()
if (saveResult) {
log("保存翻譯成功")
} else {
loge("保存翻譯失敗")
}
} catch (e: Exception) {
e.printStackTrace()
loge("保存翻譯失敗")
}
}
}
History實(shí)體類
@Keep
class History : LitePalSupport() {
var srcText: String = ""
var sl: String = "en"
var tl: String = "en"
var time: Long = 0
var liked: Int = 0
//全路徑
var ttsPath: String = ""
var result: String = ""
}
每次請(qǐng)求就先獲取本地記錄
val history = DBHelper.getHistory(content, sl, translateLanguage)
val translationBean =
JsonHelper.json2Object(history?.result ?: "", TranslationBean::class.java)
if (translationBean != null) {
parse(translationBean)
mViewRef?.get()?.refreshLiked(history?.liked == 1)
val translateText = TranslationHelper.getTranslateText(translationBean)
if (translateText.isNotEmpty()) {
play(translateText, translateLanguage)
copyToClipBoard(translateText)
}
log("獲取到數(shù)據(jù)庫(kù)翻譯內(nèi)容")
DBHelper.updateHistoryTime(history)
EventBus.getDefault().post(UpdateRecordEvent())
return
}
歷史記錄和單詞本
- 單詞本從數(shù)據(jù)庫(kù)中按條件查找like = 1 的記錄葱椭,除盏,四種情況就是選中所要查找的語(yǔ)言
fun getLikedHistory(sl: String, tl: String) {
run {
try {
//四種情況
var historyList = mutableListOf<History>()
if (sl.isEmpty() && tl.isEmpty()) {
//查所有
historyList =
LitePal.where("liked = ?", "1").order("time desc").find(History::class.java)
}
if (sl.isNotEmpty() && tl.isNotEmpty()) {
historyList = LitePal
.where("sl = ? and tl = ? and liked = ?", sl, tl, "1")
.order("time desc")
.find(History::class.java)
}
if (sl.isEmpty() && tl.isNotEmpty()) {
historyList = LitePal
.where("tl = ? and liked = ?", tl, "1")
.order("time desc")
.find(History::class.java)
}
if (sl.isNotEmpty() && tl.isEmpty()) {
historyList = LitePal
.where("sl = ? and liked = ?", sl, "1")
.order("time desc")
.find(History::class.java)
}
val wordItemList = mutableListOf<WordItem>()
historyList.map {
val wordItem = WordItem()
wordItem.history = it
wordItem.checked = false
wordItemList.add(wordItem)
}
mViewRef?.get()?.updateWordList(wordItemList)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
- 歷史記錄就是全部記錄,四種情況就是選中所要查找的語(yǔ)言
fun getHistory(sl: String, tl: String) {
run {
try {
//四種情況
var historyList = mutableListOf<History>()
if (sl.isEmpty() && tl.isEmpty()) {
//查所有
historyList = (LitePal.order("time desc").find(History::class.java))
}
if (sl.isNotEmpty() && tl.isNotEmpty()) {
historyList = LitePal
.where("sl = ? and tl = ?", sl, tl)
.order("time desc")
.find(History::class.java)
}
if (sl.isEmpty() && tl.isNotEmpty()) {
historyList = LitePal
.where("tl = ?", tl)
.order("time desc")
.find(History::class.java)
}
if (sl.isNotEmpty() && tl.isEmpty()) {
historyList = LitePal
.where("sl = ?", sl)
.order("time desc")
.find(History::class.java)
}
val wordItemList = mutableListOf<WordItem>()
historyList.map {
val wordItem = WordItem()
wordItem.history = it
wordItem.checked = false
wordItemList.add(wordItem)
}
mViewRef?.get()?.updateWordList(wordItemList)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
數(shù)據(jù)備份和恢復(fù)功能
將所有History記錄取出來(lái)挫以,封裝成BackupBean者蠕,再轉(zhuǎn)成json保存到文件中
val historyList = DBHelper.getAllHistory()
if (historyList.isEmpty()) {
toast(R.string.no_backup_data)
task.run()
return
}
val backupBean = BackupBean()
backupBean.data = historyList
val result = Gson().toJson(backupBean)
log("backupResult = $result")
val success = FileUtil.saveStringToFile(result, BACKUP_FILE_PATH)
if (success) {
toast(R.string.backup_success)
} else {
toast(R.string.backup_fail)
}
...
最后一個(gè)是百度的語(yǔ)音識(shí)別功能
項(xiàng)目中集成了百度語(yǔ)音識(shí)別,但控件被隱藏掐松,邏輯還是有的踱侣,通過(guò)一個(gè)ImageView觸發(fā)。
識(shí)別功能封裝在baiduvoice模塊中的BaiduVoiceHelper
object BaiduVoiceHelper : EventListener {
private var mEventManager: EventManager? = null
private var mRecognizedListenerList = mutableListOf<RecognizedListener>()
private var mRecognizedType: RecognizedType = RecognizedType.CHINESE
// private var mListener: RecognizedListener? = null
//重新識(shí)別
private var mNeedReRecognized = true
fun init() {
mEventManager = EventManagerFactory.create(App.context, "asr")
mEventManager?.registerListener(this)
}
fun setRecognizedListener(recognizedListener: RecognizedListener) {
mRecognizedListenerList.add(recognizedListener)
}
fun removeRecognised(recognizedListener: RecognizedListener) {
mRecognizedListenerList.remove(recognizedListener)
}
fun startRecognize(type: RecognizedType = mRecognizedType) {
mNeedReRecognized = true
mRecognizedType = type
val params = LinkedHashMap<String, Any>()
var event: String? = null
event = SpeechConstant.ASR_START // 替換成測(cè)試的event
// 基于SDK集成2.1 設(shè)置識(shí)別參數(shù)
params[SpeechConstant.ACCEPT_AUDIO_VOLUME] = false
// params.put(SpeechConstant.NLU, "enable");
// params.put(SpeechConstant.VAD_ENDPOINT_TIMEOUT, 0); // 長(zhǎng)語(yǔ)音
// params.put(SpeechConstant.IN_FILE, "res:///com/baidu/android/voicedemo/16k_test.pcm");
// params.put(SpeechConstant.VAD, SpeechConstant.VAD_DNN);
if (mRecognizedType == RecognizedType.ENGLISH) {
params[SpeechConstant.PID] = 1737 //英語(yǔ)
} else {
params[SpeechConstant.PID] = 15362 //普通話搜索模型, 默認(rèn)
}
/* 語(yǔ)音自訓(xùn)練平臺(tái)特有參數(shù) */
// params.put(SpeechConstant.PID, 8002);
// 語(yǔ)音自訓(xùn)練平臺(tái)特殊pid大磺,8002:搜索模型類似開放平臺(tái) 1537 具體是8001還是8002抡句,看自訓(xùn)練平臺(tái)頁(yè)面上的顯示
// params.put(SpeechConstant.LMID,1068); // 語(yǔ)音自訓(xùn)練平臺(tái)已上線的模型ID,https://ai.baidu.com/smartasr/model
// 注意模型ID必須在你的appId所在的百度賬號(hào)下
/* 語(yǔ)音自訓(xùn)練平臺(tái)特有參數(shù) */
// 請(qǐng)先使用如‘在線識(shí)別’界面測(cè)試和生成識(shí)別參數(shù)杠愧。 params同ActivityRecog類中myRecognizer.start(params);
// 復(fù)制此段可以自動(dòng)檢測(cè)錯(cuò)誤
AutoCheck(App.context, @SuppressLint("HandlerLeak")
object : Handler() {
override fun handleMessage(msg: Message) {
if (msg.what == 100) {
val autoCheck = msg.obj as AutoCheck
synchronized(autoCheck) {
val message =
autoCheck.obtainErrorMessage() // autoCheck.obtainAllMessage();
// txtLog.append(message + "\n")
log(message)
// Log.w("AutoCheckMessage", message);
}// 可以用下面一行替代待榔,在logcat中查看代碼
}
}
}, false).checkAsr(params)
var json: String? = null // 可以替換成自己的json
json = JSONObject(params as Map<*, *>).toString() // 這里可以替換成你需要測(cè)試的json
mEventManager?.send(event, json, null, 0, 0)
log("開始識(shí)別: 輸入?yún)?shù):$json")
}
fun stopRecognize() {
mNeedReRecognized = false
log("停止識(shí)別:ASR_STOP")
mEventManager?.send(SpeechConstant.ASR_STOP, null, null, 0, 0) //
}
fun destroy() {
stopRecognize()
mEventManager?.unregisterListener(this)
}
// 基于sdk集成1.2 自定義輸出事件類 EventListener 回調(diào)方法
// 基于SDK集成3.1 開始回調(diào)事件
override fun onEvent(
name: String,
params: String?,
data: ByteArray?,
offset: Int,
length: Int
) {
var logTxt = "name: $name"
if (params != null && !params.isEmpty()) {
logTxt += " ;params :$params"
}
if (data != null) {
logTxt += " ;data length=" + data.size
}
log(logTxt)
if (params?.contains("final_result") == true) {
loge("最后識(shí)別結(jié)果: $logTxt")
try {
val jsonObject = JSONObject(params)
val result = jsonObject.getString("best_result")?:""
mRecognizedListenerList.map {
it.onResult(params, result)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
if (name == "asr.exit" && mNeedReRecognized) {
startRecognize()
//重新識(shí)別
}
}
}
用到的開源項(xiàng)目
- Eventbus
- LitePal: 數(shù)據(jù)庫(kù)
- RxJava/RxAndroid
- Retrofit/Okhttp
- Glide
更多項(xiàng)目
最后
如果喜歡,請(qǐng)star
最重要一點(diǎn),請(qǐng)勿商用锐锣。
如非必要腌闯,請(qǐng)更改包名,類名雕憔,包結(jié)構(gòu)姿骏。
謝謝。
我的Github