| <html devsite> |
| <head> |
| <title>Implementing Text Classification</title> |
| <meta name="project_path" value="/_project.yaml" /> |
| <meta name="book_path" value="/_book.yaml" /> |
| </head> |
| <body> |
| {% include "_versions.html" %} |
| <!-- |
| Copyright 2017 The Android Open Source Project |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| |
| |
| <p>Text classification uses machine learning techniques to help developers classify text.</p> |
| |
| <h2>Android {{ androidPVersionNumber }} release text classification enhancements</h2> |
| |
| <p>Android {{ androidPVersionNumber }} extended the <a |
| href="#8_1release">text |
| classification framework introduced in Android 8.1</a> with the new Text |
| Classifier service. The Text Classifier service is the recommended way for OEMs |
| to provide text classification system support. The Text Classifier service may |
| be part of any system APK and may be updated when necessary.</p> |
| |
| <p>Android {{ androidPVersionNumber }} includes a default Text Classifier service implementation (<a |
| href="https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/view/textclassifier/TextClassifierImpl.java"> |
| <code>TextClassifierImpl</code></a>) that is used unless you replace it with a custom Text Classifier service |
| implementation.</p> |
| |
| <h3>Implementing a custom Text Classifier service</h3> |
| <p>The following sections describe how to implement a custom Text Classifier |
| service that you develop.</p> |
| |
| <h4>Extend android.service.textclassifier.TextClassifierService</h4> |
| <p><pre class="prettyprint"> |
| public final class TextClassifierServiceImpl |
| extends TextClassifierService { |
| |
| // Returns TextClassifierImpl. |
| private final TextClassifier tc = getLocalTextClassifier(); |
| |
| @Override |
| public void onSuggestSelection( |
| @Nullable TextClassificationSessionId sessionId, |
| @NonNull TextSelection.Request request, |
| @NonNull CancellationSignal cancellationSignal, |
| @NonNull Callback<TextSelection> callback) { |
| CompletableFuture.supplyAsync( |
| () -> tc.suggestSelection(request)) |
| .thenAccept(r -> callback.onSuccess(r)); |
| } |
| |
| @Override |
| public void onClassifyText( |
| @Nullable TextClassificationSessionId sessionId, |
| @NonNull TextClassification.Request request, |
| @NonNull CancellationSignal cancellationSignal, |
| @NonNull Callback<TextClassification> callback) { |
| ... |
| } |
| |
| @Override |
| public void onGenerateLinks( |
| @Nullable TextClassificationSessionId sessionId, |
| @NonNull TextLinks.Request request, |
| @NonNull CancellationSignal cancellationSignal, |
| @NonNull Callback<TextLinks> callback) { |
| ... |
| } |
| ... |
| } |
| </pre> |
| </p> |
| |
| <h4>Define the service in the Android manifest</h4> |
| |
| <p><em>[AndroidManifest.xml]</p></em> |
| <p><pre class="prettyprint"> |
| <service android:name=".TextClassifierServiceImpl" |
| android:permission="android.permission.BIND_TEXTCLASSIFIER_SERVICE"> |
| <intent-filter> |
| <action android:name= |
| "android.service.textclassifier.TextClassifierService"/> |
| </intent-filter> |
| </service> |
| </pre></p> |
| |
| <p> |
| Note that the service must require the |
| <code>android.permission.BIND_TEXTCLASSIFIER_SERVICE</code> permission and must |
| also specify the |
| <code>android.service.textclassifier.TextClassifierService</code> Intent |
| action.</p> |
| |
| <h4>Set a system default Text Classifier service in the config overlay</h4> |
| <p>[<em>config.xml</em>]</p> |
| <p><pre class="prettyprint"> |
| <string name="config_defaultTextClassifierPackage" translatable="false">com.example.textclassifierservice</string></pre></p> |
| |
| <h4>Build the Text Classifier service into the system image</h4> |
| <p>Your custom Text Classifier service can be a standalone APK that is built into the system image |
| or a part of another system APK. The system uses <code>PackageManager.MATCH_SYSTEM_ONLY</code> |
| to resolve the service. |
| </p> |
| |
| <h3>Testing</h3> |
| |
| <p>Run Tests in <code>android.view.textclassifier.cts</code></p> |
| |
| <h3>Other text classification changes in Android {{ androidPVersionNumber }}</h3> |
| |
| <p>Refer to <a |
| href="https://source.android.com/devices/tech/display/textclassifier#inspecting-installed-language-modules"> |
| Inspecting installed language modules</a>.</p> |
| <p>Android {{ androidPVersionNumber }} model files are incompatible with |
| Android 8.x model files.</p> |
| <p>Android {{ androidPVersionNumber }} model files have the naming pattern: |
| <code>texclassifier.[language-code].model</code> (e.g. |
| <code>textclassifier.en.model</code>) |
| instead of <code>textclassifier.smartselection.en.model</code> in Android 8.x.</p> |
| |
| <h3>Obtaining the latest text classification model files</h3> |
| <p>To obtain the most up-to-date models the following script can be run, which |
| updates the TextClassifier models in the source tree:</p> |
| |
| <p><pre class="devsite-terminal devsite-click-to-copy"> |
| <a href="https://android.googlesource.com/platform/external/libtextclassifier/+/master/models/">external/libtextclassifier/models/</a>update.sh</pre></p> |
| |
| |
| <h2 id="8_1release">Android release 8.1 text classification</h2> |
| |
| <p>Android 8.1 introduced the TextClassfier API to implement text classification</p> |
| |
| <pre |
| class="prettyprint">TextClassificationManager tcm = |
| context.getSystemService(TextClassificationManager.class); |
| TextClassifier classifier = tcm.getTextClassifier(); |
| TextSelection selection = classifier.suggestSelection(...); |
| TextClassification classification = classifier.classifyText(...); |
| </pre> |
| <p> |
| Developers may choose to set a custom text classifier: |
| </p> |
| <p> |
| <code>tcm.setTextClassifier(customTextClassifier);</code> |
| </p> |
| <p> |
| But if an app developer sets the text classifier to null, a system default text |
| classifier is returned for <code>getTextClassifier()</code>. |
| </p> |
| <p> |
| See: <code>android.view.textclassifier.TextClassifierImpl</code> |
| </p> |
| <p> |
| TextView and WebView use the TextClassifier for smart selection and smart text |
| share features: |
| </p> |
| |
| <img src="/devices/tech/display/images/textclassifier.png"> |
| <p class="img-caption"> |
| <b>Figure 1.</b> TEXTCLASSIFIER usage. |
| </p> |
| |
| <h3 id="textclassifier-neural-net-models">TextClassifier neural-net models</h3> |
| <p> |
| The Android Open Source Project (AOSP) features a number of neural network |
| models for classifying text. Each model file is trained for a single language. |
| You may choose to install any combination of models. The models are defined in: |
| </p> |
| <p> |
| <code>external/libtextclassifier/Android.mk</code> |
| </p> |
| |
| <h3 id="pre-installing-language-models-on-devices">Pre-installing language |
| models on devices</h3> |
| <p> |
| You may specify a bundle of language models and install them on a device: |
| </p> |
| |
| |
| <pre |
| class="prettyprint"># ----------------------- |
| # Smart Selection bundles |
| # ----------------------- |
| |
| include $(CLEAR_VARS) |
| LOCAL_MODULE := textclassifier.smartselection.bundle1 |
| LOCAL_REQUIRED_MODULES := textclassifier.smartselection.en.model |
| LOCAL_REQUIRED_MODULES += textclassifier.smartselection.es.model |
| LOCAL_REQUIRED_MODULES += textclassifier.smartselection.de.model |
| LOCAL_REQUIRED_MODULES += textclassifier.smartselection.fr.model |
| include $(BUILD_STATIC_LIBRARY) |
| </pre> |
| |
| <p> |
| For example, in <code>device/google/marlin/device-common.mk</code> |
| </p> |
| |
| |
| <pre |
| class="prettyprint"># TextClassifier smart selection model files |
| PRODUCT_PACKAGES += \ |
| textclassifier.smartselection.bundle1 |
| </pre> |
| |
| <h3 id="inspecting-installed-language-modules">Inspecting installed language |
| modules</h3> |
| <p> |
| Use ADB to list the files in the directory: |
| </p> |
| |
| |
| <pre |
| class="prettyprint">$ adb shell ls -l /etc/textclassifier |
| -rw-r--r-- 1 root root ... textclassifier.smartselection.de.model |
| -rw-r--r-- 1 root root ... textclassifier.smartselection.en.model |
| -rw-r--r-- 1 root root ... textclassifier.smartselection.es.model |
| -rw-r--r-- 1 root root ... textclassifier.smartselection.fr.model |
| </pre> |
| |
| <h3 id="gservices-model-updates">Model updates</h3> |
| |
| <p> |
| Models can be updated either by having a new model included as part of a system image update, |
| or dynamically via having a system component that would trigger an update through the |
| System <code>API ACTION_UPDATE_SMART_SELECTION</code> intent. By broadcasting this System API |
| intent, the framework is able to update the language model of the currently set language. |
| The models themselves contain the supported |
| language and a version number so the latest appropriate model is used. |
| </p> |
| |
| <p> |
| So you don't need to preload models for all languages because they can be added later. |
| If no model file is found for the specified language, text classification will return no-op values. |
| </p> |
| |
| <h3 id="compatibility-test-suite-tests">Compatibility Test Suite tests</h3> |
| <p> |
| The associated Android Compatibility Test Suite (CTS) tests can be found in: |
| </p> |
| <p> |
| <code>cts/tests/tests/view/src/android/view/textclassifier/cts/TextClassificationManagerTest.java</code> |
| </p> |
| <p> |
| <code>cts/tests/tests/widget/src/android/widget/cts/TextViewTest.java</code> |
| </p> |
| |
| <ul> |
| <li><code>testSmartSelection</code></li> |
| <li><code>testSmartSelection_dragSelection</code></li> |
| <li><code>testSmartSelection_resetSelection</code></li> |
| </ul> |
| |
| </body> |
| </html> |