【翻譯】TextClassification介紹(三)

TextClassification介紹(一)

一闸天、說明

這是一個(gè)關(guān)于介紹 TextClassification API 的系列文章侥钳,總共分三篇呈枉,本文是最后一篇刹勃。上一篇在此:【翻譯】TextClassification介紹(二)

原文作者:Mark Allison
閱讀時(shí)間: 5 分鐘
原文鏈接:https://blog.stylingandroid.com/textclassification-part-3/

二堪侯、正文

在 API 26 (奧利奧)中安卓引入了一個(gè)新的文字功能系統(tǒng): TextClassification 。這個(gè)系統(tǒng)將會(huì)在 API 28 ( π )中進(jìn)一步改進(jìn)完善深夯。在本次簡(jiǎn)短的系列中抖格,我們主要會(huì)探討它是一個(gè)什么樣的系統(tǒng),如何使用它咕晋,以及如何為它添加一些自定義行為。

上一篇文章中我們開始研究自定義 TextClassifier 的實(shí)現(xiàn)收奔,并研究了如何實(shí)現(xiàn)我們自己的“文本選擇建議”掌呜。在本系列的最后一篇文章中,我們將會(huì)實(shí)現(xiàn)相應(yīng)的 classifyText() 方法坪哄,并應(yīng)用到我們自定義的 TextClassifier 文本分類器的實(shí)現(xiàn)中质蕉。

這里的 classifyText() 方法的實(shí)現(xiàn)實(shí)際上非常簡(jiǎn)單直接。我們檢查選擇的文本是否與請(qǐng)求中所選擇的相匹配翩肌,如果相匹配則返回一個(gè) TextClassification 的實(shí)例模暗,這個(gè)我們稍后再詳細(xì)了解。如果選擇的文本與我們的正則表達(dá)式不匹配念祭,那么我們會(huì)將結(jié)果進(jìn)行回滾(也就是 TextClassifier 的默認(rèn)實(shí)現(xiàn)):

override fun classifyText(request: TextClassification.Request): TextClassification {
    //line 36
    return if (regex.matches(request.subSequence())) {
        factory.buildTextClassification(
                //line 38
                request.subSequence().toString(),
                listOf(TextClassifier.TYPE_URL to 1.0f),
                listOf(factory.buildRemoteAction(
                        context,
                        R.drawable.ic_stylingandroid,
                        stylingAndroid,
                        contentDescription,
                        stylingAndroidUri
                ))
        )
    } else {
        fallback.classifyText(request)
    }
}

private fun TextClassification.Request.subSequence() =
        text.subSequence(startIndex, endIndex)

這里有一個(gè) TextClassification.Request 的擴(kuò)展函數(shù)兑宇,它返回文本中已選擇的子文本 subSequence ,我們正是使用它來匹配正則表達(dá)式(第 36 行)粱坤。然后隶糕,我們構(gòu)建一個(gè) TextClassification 對(duì)象瓷产,它需要一些參數(shù),包括匹配到的字符串(第 38 行)枚驻,分類類型與其各自的可信度分?jǐn)?shù)列表(第 39 行)濒旦,以及一列 RemoteAction 實(shí)例對(duì)象,每個(gè) RemoteAction 對(duì)象對(duì)應(yīng)一個(gè)分類類型條目(第 39-45 行)再登。

這里的 buildRemoteAction() 方法返回每個(gè) RemoteAction 實(shí)例:

override fun buildRemoteAction(
        context: Context,
        drawableId: Int,
        title: String,
        contentDescription: String,
        uri: String
): RemoteAction {
    return RemoteAction(
            Icon.createWithResource(context, drawableId),
            title,
            contentDescription,
            PendingIntent.getActivity(
                    context,
                    0,
                    Intent(Intent.ACTION_VIEW, Uri.parse(uri)),
                    0
            )
    )
}

這里 RemoteAction 的構(gòu)造函數(shù)需要四個(gè)參數(shù):一個(gè) Icon 對(duì)象尔邓,它將顯示為操作按鈕中的一部分;一個(gè)要顯示的文字锉矢;一個(gè)表示可訪問的內(nèi)容描述梯嗽;最后還需一個(gè) PendingIntent 對(duì)象,它表示用戶在點(diǎn)擊操作按鈕時(shí)將會(huì)執(zhí)行的操作沈撞。在我們的示例代碼中慷荔,我們使用了一個(gè) Styling Android 標(biāo)志圖形作為圖標(biāo),使用了 “Styling Android” 作為標(biāo)題缠俺,以及簡(jiǎn)單的一些內(nèi)容描述显晶,再加一個(gè)能登錄瀏覽器打開 URL 鏈接 "https://blog.stylingandroid.com" 的 PendingIntent 對(duì)象。

buildTextClassification() 函數(shù)使用 TextClassification.Builder 實(shí)例來創(chuàng)建 TextClassification 對(duì)象:

override fun buildTextClassification(
        text: String,
        entityTypes: List<Pair<String, Float>>,
        actions: List<RemoteAction>
): TextClassification {
    return TextClassification.Builder()
            .run {
                setText(text)
                entityTypes.forEach { setEntityType(it.first, it.second) }
                actions.forEach { addAction(it) }
                build()
            }
}

這里需要傳遞三個(gè)參數(shù):匹配到的文本壹士,一系列以類型及其對(duì)應(yīng)的可信度范圍作為 Pair 的列表磷雇,以及與每個(gè)類型/置信度組合所對(duì)應(yīng)的 RemoteActions 列表。在這里示例中躏救,這些參數(shù)分別是被選定的子字符串唯笙,包含一對(duì) TextClassifier.TYPE_URL 及其可信度為 1.0f 組成的 Pair 的列表,以及一列包含我們剛剛說過的 RemoteAction 類單例的列表盒使。

TextClassifier 已經(jīng)完成了崩掘,剩下的事情就是將它連接到我們的 TextView 文本控件中:

class MainActivity : AppCompatActivity() {

    private val emailText = "dummy@email.com"
    private val urlText = "https://blog.stylingandroid.com"
    private val hybridText = "Email: $emailText"

    private lateinit var textClassificationManager: TextClassificationManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        textClassificationManager = getSystemService(Context.TEXT_CLASSIFICATION_SERVICE) as TextClassificationManager

        classifier()

        text1.textClassifier = StylingAndroidTextClassifier(this, textClassificationManager.textClassifier)
    }

    private fun classifier() = async(CommonPool) {
        val textClassifier = textClassificationManager.textClassifier
        val emailClassification = textClassifier.classifyText(emailText, 0, emailText.length, LocaleList.getDefault())
        println(emailClassification)
        val urlClassification = textClassifier.classifyText(urlText, 0, urlText.length, LocaleList.getDefault())
        println(urlClassification)
        val suggestions = textClassifier.suggestSelection(hybridText, 10, 11, LocaleList.getDefault())
        println(suggestions)
    }
}

一行代碼就可以實(shí)現(xiàn)我們要做的一切。我們創(chuàng)建了一個(gè)自定義 TextClassifier 對(duì)象少办,并將其作為參數(shù)傳遞給默認(rèn)的 TextClassifier 對(duì)象的構(gòu)造函數(shù)苞慢,并將 TextViewtextClassifier 屬性設(shè)置為我們的自定義實(shí)例。

我們目前得到的文本處理行為是:如果用戶長(zhǎng)時(shí)間按下的文字是無法識(shí)別的類型英妓,那就只有簡(jiǎn)單的復(fù)制挽放,粘貼和選擇所有的選項(xiàng)功能;如果他們長(zhǎng)時(shí)間按下系統(tǒng)默認(rèn)的文本分類器所支持的任何類型蔓纠,那么他們會(huì)得到我們?cè)诘谝黄恼轮兴吹降乃邢嗤男袨楹蛣?dòng)作辑畦;但是,如果他們長(zhǎng)按 "Styling Android" 字符串(或者與正則表達(dá)式相匹配的類似字符串)腿倚,那么將獲得我們所自定義的“流行廣告”操作纯出,這個(gè)操作將啟動(dòng)瀏覽器并登錄加載鏈接: https://blog.stylingandroid.com

custom.gif

TextClassifier 文本分類器中還有一個(gè)機(jī)制,用來識(shí)別具體的文本類型,然后使用文本生成鏈接潦刃,不過在本系列文章中我們不會(huì)去研究它侮措,因?yàn)槲覀冞@里所看到的技術(shù)已經(jīng)涵蓋了 TextViewWebView 內(nèi)置的一些主要功能。如果看到這里有人對(duì)此感興趣乖杠,那么請(qǐng)告訴我分扎,我將會(huì)單獨(dú)寫一篇文章作詳細(xì)說明。

三胧洒、總結(jié)

這篇文章的源代碼可以在這里找到: https://github.com/StylingAndroid/TextClassification/tree/Part3畏吓。

? 2018 , Mark Allison 卫漫。保留所有版權(quán)菲饼。

我的博客地址: http://liuqingwen.me ,歡迎關(guān)注我的微信公眾號(hào):

IT自學(xué)不成才

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末列赎,一起剝皮案震驚了整個(gè)濱河市宏悦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌包吝,老刑警劉巖饼煞,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異诗越,居然都是意外死亡砖瞧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門嚷狞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來块促,“玉大人,你說我怎么就攤上這事床未〗叽洌” “怎么了?”我有些...
    開封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵薇搁,是天一觀的道長(zhǎng)逃片。 經(jīng)常有香客問我,道長(zhǎng)只酥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任呀狼,我火速辦了婚禮裂允,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘哥艇。我一直安慰自己绝编,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著十饥,像睡著了一般窟勃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上逗堵,一...
    開封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天秉氧,我揣著相機(jī)與錄音,去河邊找鬼蜒秤。 笑死汁咏,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的作媚。 我是一名探鬼主播攘滩,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼纸泡!你這毒婦竟也來了漂问?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤女揭,失蹤者是張志新(化名)和其女友劉穎蚤假,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體田绑,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡勤哗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掩驱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芒划。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖欧穴,靈堂內(nèi)的尸體忽然破棺而出民逼,到底是詐尸還是另有隱情,我是刑警寧澤涮帘,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布拼苍,位于F島的核電站,受9級(jí)特大地震影響调缨,放射性物質(zhì)發(fā)生泄漏疮鲫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一弦叶、第九天 我趴在偏房一處隱蔽的房頂上張望俊犯。 院中可真熱鬧,春花似錦伤哺、人聲如沸燕侠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绢彤。三九已至七问,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間茫舶,已是汗流浹背械巡。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奇适,地道東北人坟比。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像嚷往,于是被迫代替她去往敵國(guó)和親葛账。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容