1. 始める前に
この Codelab は、モバイル テキスト分類を使ってみるパスウェイのアクティビティ #2 です。
この Codelab では、シンプルなメッセージ アプリを作成します。このパスウェイの後半では、このアプリを更新して、アプリのメッセージから不要なスパムをフィルタする機械学習モデルを追加します。
前提条件
- Kotlin による Android 開発、および(必要に応じて)Swift による iOS 開発に関する基本的な知識
作成するアプリの概要
- シンプルなメッセージ アプリ
必要なもの
- Android の場合、まず Android Studio が必要になります。続行する前に、インストールと完全な更新が完了していることを確認してください。
- iOS の場合は Xcode が必要です。App Store で入手できます。(iOS アプリのみを作成する場合は、手順 5 に進みます。
コードを取得
ステップごとに進めるのではなく、このパスウェイの最終的なコードを確認したい場合は、
git clone https://github.com/googlecodelabs/odml-pathways
TextClassificationOnMobile ディレクトリを見つけ、その中に Android と iOS のサブディレクトリがあることを確認します。これらのディレクトリには TextClassificationStep1 サブディレクトリが含まれており、それぞれ Android と iOS のアプリが含まれています。

2. Android Studio で新しいプロジェクトを作成する
- Android Studio を起動します。

- [新しいプロジェクトを作成] を選択します。プロジェクト テンプレートの選択を求めるダイアログが表示されます。
- [Empty Activity] を選択して、[Next] をクリックします。次に、プロジェクトの構成を求められます。お好きなものを選択してください。ただし、言語が Kotlin で、最小 SDK が API 23 であることを確認してください。
- [完了] をクリックします。完了すると、Android Studio がプロジェクトとともに開きます。特に Android Studio を初めて使用する場合は、すべてが正常に動作するように Gradle 同期を実行するのに数分かかることがあります。
3. ユーザー インターフェースを作成する
Android アプリのユーザー インターフェースは、レイアウト ファイルと呼ばれる XML ファイルを使用して作成されます。
- ファイルを開きます。Android Studio のエクスプローラで、[app] > [res] > [layout] > [activity_main.xml] をクリックします。

画面の右上に、次のように [Code]、[Split]、[Design] のタブがある選択が表示されます。

次のステップに進む前に、[Code] が選択されていることを確認してください。
- コードを次の XML に置き換えます。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enter a string:"></TextView>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/txtInput"></EditText>
</LinearLayout>
<TextView
android:id="@+id/txtOutput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Output Goes here"
android:textSize="36sp"></TextView>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnSendText"
android:text="Send"></Button>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
これにより、TextView を含む入力領域が表示され、Enter a String(文字列を入力)というプロンプトと、文字列の入力に使用できる txtInput という EditText が表示されます。その下には、出力をレンダリングする TextView と、ユーザーが分類をトリガーするために押すボタンがあります。
次のステップでは、このユーザー インターフェースを有効にするコードを記述します。
4. コントロールを接続してアプリを作成する
このアクティビティのコードを編集するには、MainActivity コードファイルを見つけます。
- Android Studio で、[app] > [java] > [MainActivity] をクリックします。

- MainActivity ファイルを開いてコードエディタを表示します。このファイル内の「package」で始まる最初の行以外のすべてを次のコードに置き換えます。
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
class MainActivity : AppCompatActivity() {
lateinit var txtInput: EditText
lateinit var btnSendText: Button
lateinit var txtOutput: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
txtInput = findViewById(R.id.txtInput)
txtOutput = findViewById(R.id.txtOutput)
btnSendText = findViewById(R.id.btnSendText)
btnSendText.setOnClickListener {
var toSend:String = txtInput.text.toString()
txtOutput.text = toSend
}
}
}
このコードは、レイアウトのコントロールを txtInput、txtOutput、btnSendText に接続し、コードでアドレス指定できるようにします。次に、ボタンの OnClickListener を設定します。これにより、ユーザーがボタンをタップすると、txtInput のテキストが読み取られ、String に変換されて、txtOutput.text プロパティに設定されます。
5. iOS で Basic アプリを作成する
以下の手順では、Xcode と Swift を使用した iOS 開発に関するある程度の知識が必要です。
作成プロセスを行いたくない場合は、リポジトリを複製してアプリを直接開くことができます。TextClassificationStep1 という名前で、リポジトリの iOS フォルダにあります。
基本的なアプリを作成するには、まず Xcode を使用します。
- 基本テンプレートを使用して新しいアプリを作成します。

- 新しいプロジェクトのオプションを選択します。プロダクトに名前と組織 IDを付けます。入力するか、次の例に沿って操作します(ただし、図に示すように、インターフェースを [Storyboard] に、ライフサイクルを [UIKitApp Delegate] に設定してください)。

6. ストーリーボードを編集する
- Main.storyboard を開きます。コントロールを追加できるデザイン サーフェスが表示されます。
- コントロールを追加するには、Xcode ウィンドウの上部にある + ボタンをクリックします。

- これを使用して、TextView コントロール、Button コントロール、Label コントロールをデザイン サーフェスに配置します。次のようになります。

- アシスタントを使用して、ストーリーボードと ViewController.swift ファイルの両方が開いた状態で並べて表示します。アシスタントは、画面の右上に表示される小さなアイコンです(下図を参照)。

- CONTROL キーを押しながら、TextView コントロールをコード サーフェスにドラッグします。ドラッグすると青い矢印が表示されます。
- クラス宣言のすぐ下のコードにドロップします。接続タイプを尋ねるポップアップが表示されます。次のようになります。

- [Outlet] を選択し、txtInput という名前を付けます。
- ラベルについても同様に設定し、接続タイプを [Outlet] にして、txtOutput という名前を付けます。
- 最後に、ボタンをドラッグしますが、今回は接続タイプとして [アクション] を選択します。(接続タイプとして [Outlet] は使用しないでください)。
- アクションに btnSendText という名前を付けます。
完了すると、クラスの先頭のコードは次のようになります。
@IBOutlet weak var txtInput: UITextView!
@IBOutlet weak var txtOutput: UILabel!
@IBAction func btnSendText(_ sender: Any) {
}
7. 基本的な iOS アプリのコーディングを完了する
このビューは UITextView を使用しているため、このビューのイベントに応答するには、UITextViewDelegate である必要があります。
クラス宣言を次のように変更すると、この値を取得できます。
class ViewController: UIViewController, UITextViewDelegate {
次に、viewDidLoad 関数で、UITextView(アウトレットを設定したときに txtInput と呼びました)のデリゲートを次のようにこのクラスに設定します。
override func viewDidLoad() {
super.viewDidLoad()
txtInput.delegate = self
}
最後に、ユーザーがキーボードで Enter キーを押したら、キーボードを非表示にする処理を行います。これは、設定した委任を通じて行われます。このメソッドを ViewController に実装して処理できます。
func textView(_ textView: UITextView, shouldChangeTextIn range:
NSRange, replacementText text: String) -> Bool {
if (text == "\n") {
textView.resignFirstResponder()
return false
}
return true
}
このアプリではボタンの動作は簡単で、ユーザーが入力した内容を出力に渡すだけです。後で、NLP モデルがこのテキストをフィルタリングする方法について説明します。ここでは、パススルーをシミュレートするために、配線してみましょう。
アクション btnSendText はすでに作成済みなので、あとはそのアクションにコードを追加するだけです。
@IBAction func btnSendText(_ sender: Any) {
txtOutput.text = "Sent :" + txtInput.text
}
8. 完了
これでこの Codelab は終了です。
このパスウェイの次のステップでは、NLP モデルを作成する方法を学習します。このモデルは後でこのアプリに戻して、ユーザーのテキストからコメント スパムをフィルタできるようにします。