自分だけのスペイン語検索ログを作る スマホ編

構想編の続きです。

androidアプリでやりたいことを整理すると以下の3つです。

1.文字選択メニューに自作アプリを出す

2.サーバーに選択文字列を送る

3.サーバーから受け取った結果をアプリに反映させる

 

開発環境はAndroid Studio bumblebee(2021)で作ることを想定しています。

やっていることが分かりやすい様にプロジェクトテンプレートのEmpty Activityをベースに作成します。

テンプレートのうち修正したファイルだけgitへ上げておきます。(https://github.com/samsumario/blog_public/tree/main/blog_3110)

コードはkotlinで、プロジェクトの対象OSはAndroid10.0(Q)以上としていますが多分殆どのバージョンで動くと思います。

 

1.文字選択メニューに自作アプリを出す

少し専門的に言うとIntentでアプリを起動するというみたいで、マニフェストに書きます。(全文 : AndroidManifest.xml)

intent起動用の専用クラスを作っているサンプルもありましたが、今回は最小実装をしたいのでMainActivity内のintent-filterに追加してMainActivityクラスで処理します。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/mysample/android"
    package="com.example.mysample">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.mysample">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PROCESS_TEXT" />

                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

23~28行目が追加したintent処理部分です。

アプリ内でネット接続をするために5,6行目にpermissionも追加しています。

そのほかの部分はテンプレートのままです。

 

2.サーバーに選択文字列を送る

送ると言ってもURLを開く様な感じです。詳しく言うとHTTP通信のGETメソッドで行います。

1から作るのは大変そうなので今回はokhttp3というライブラリを使いました。

build.gradle(Moduleの方)のdependenciesにokhttp3をバージョンべた書きで追記します。早さ優先です。

下記のなんちゃってdependenciesの3行目がテンプレートからの追加部分で今回使ったバージョンは4.9.0です。

編集後にsyncさせて完了です。(build.gradel全文はこちら)

dependencies {
   ・・・(元からあるimplementation)
    implementation 'com.squareup.okhttp3:okhttp:4.9.0'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

 

ManifestとGradleの下準備が終わったので次はMainActivityのコーディングをします。

コーディング内容は下記3点。

1.選択文字列を取得する

2.GETのURLを指定する

3.okhttpのクライアントとリクエストのインスタンスを作る

既にテンプレートで用意されているsetContentViewの下に続けて書きます。(コード全文はこちら)

val intentText = intent.getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT)?.toString()
val baseURL = "https://my-api/?word="
if (intentText != null) {
            if(intentText.isNotEmpty()) {
                        val client = OkHttpClient.Builder().build()
                        val request = Request.Builder()
                                .url("$baseURL${intentText.lowercase()}")
                                .build()
                                 ・・・(続く)・・・

3行目と4行目で一応選択文字のnull除けをしています。

2行目のbaseURLはあくまでサンプルですが今回はwordという変数に選択文字を入れてサーバーに送ることを想定しています。

7行目は取得した選択文字を小文字化してbaseURLとくつっけてurlを生成しています。(ただの文字列です)

まだサーバーへ送信していませんがひとまずここまで。

 

3.サーバーから受け取った結果を反映させる

サーバーとの通信はandroidのお約束でUIスレッド(メインスレッド)で出来ません。

大きな理由は通信中にアプリが固まるからでスレッドやらコルーチンやらを使ったサンプルが大量に出て来ます。。。が、今回はあくまでサクッと作りたいのでその辺の事情はokhttpライブラリにお任せすることにします。

enqueueメソッドが一番やり易そうだったので、さっき書いたMainActivity.ktファイルに続けて下記の用に実装しました。(コード全文はこちら)

client.newCall(request).enqueue(object : Callback {
                    override fun onFailure(call: Call, e: IOException) {
                        runOnUiThread {
                            val tv = findViewById<TextView>(R.id.hellowworld)
                            tv.text = "error: $e"
                        }
                    }

                    @SuppressLint("SetTextI18n")
                    override fun onResponse(call: Call, response: Response) {
                        runOnUiThread {
                            val jsonText = response.body!!.string()
                            val tv = findViewById<TextView>(R.id.hellowworld)
                            tv.text = jsonText
                        }
                    }
                })

Callbackの中でonFailure(通信エラー時処理)とonResponse(データ受信時処理)をオーバーライドしているだけの簡単なものを用意しました。

onFailureの中身はempry activityに唯一あるtext viewにエラーメッセージを張り付けるだけです。

textviewのidだけ付け加えています。(レイアウト全文はこちら

onResponseの中身は受け取ったデータをやっぱりtext viewに貼り付けるだけで今回は済ませます。

12行目の処理は作っていくうちに色々なデータをやり取りしたくなる気がするので敢えてjson形式でのレスポンスを想定した実装にしました。

 

以上でandroidアプリ側は完了です。

コメントを残す

メールアドレスが公開されることはありません。