Arduinoとスマホでお家をモニタPart2.5【Bletooth選択動作の作成】

# 初めに
[前回](https://qiita.com/Antareskkudo/items/e102d5c4aebff21766ea)はArduinoとBluetooth送受信機（以下、BLEデバイスとする）の接続、受信した情報をデコードするところまでやりました。今回は前回の課題に挙がっていた**BLEデバイスをコードでしか変更できない問題**について解決していこうと思います。[^1]

本記事で説明する内容の範囲は以下の通りです。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/38f77b59-4631-3900-4278-4ee7ca5f6caa.png)

# アプリ動作順序について
コードの説明の前に前提条件を理解しておきます。
前回ではアプリ起動時にプログラムされたBLEデバイスに接続する操作をしていました。今回はそのアクセス前にBLEを選択する動作を加えます。

Androidのアクティビティ実行動作順序（ライフサイクルイベント）は下のように規定されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/c9c7efe8-0c13-6dbc-9d5b-bf55bbbd1638.png)
_画像引用元：[知らずに作って大丈夫？Androidの基本的なライフサイクルイベント31選](https://atmarkit.itmedia.co.jp/ait/articles/1604/04/news011_2.html)_

前回作成したプログラムのアクティビティは上図の`onCreate()`で全て動作していました。そこで、今回は下記のようにします。
* `onCreate()`：BLEデバイスの選択 
* `onStart()`：選択されたBLEデバイスとの接続＆その他全ての操作の実行

# BLEデバイス選択用ソースコード作成
では結論として、初めにBLEデバイスの選択、接続、実行するための全てのソースコードを示します。内容は後から解説します。

## MainActivity.kt
```diff_kotlin:MainActivity.kt
//動作環境に合わせてください
package com.mongodb.housemonitor

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.util.Log
import android.content.Intent
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream

const val TAG = "MainActivity"
//前回ペアリングしたRN-42のデバイス名をRNBT-○○○○で記述していますが今回は使用しないためコメントアウト
//const val TARGET_DEVICE_NAME = "RNBT-####"
const val REQUEST_ENABLE_BLUETOOTH = 1

class MainActivity : AppCompatActivity() {
    private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()
    private var connectedThread: ConnectedThread? = null
    private var connectThread: ConnectThread? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //レイアウトのactivity_mainはonStartで使用するためここでは記載しない
        //setContentView(R.layout.activity_main)
        val intent = Intent(this, SelectActivity::class.java)
        startActivity(intent)
    }
    override fun onStart() {
        super.onStart()
        setContentView(R.layout.activity_main)
        connectThread = ConnectThread(conn_device)
        connectThread?.start()
    }

    fun manageMyConnectedSocket(socket: BluetoothSocket) {
        connectedThread = ConnectedThread(socket)
        connectedThread?.start()
    }

    private inner class ConnectThread(device: BluetoothDevice?) : Thread() {
        private val mmSocket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) {
            device?.createInsecureRfcommSocketToServiceRecord(device.uuids[0].uuid)
        }

        public override fun run() {
            // Cancel discovery because it otherwise slows down the connection.
            bluetoothAdapter?.cancelDiscovery()
            if (mmSocket == null) {
                return
            }
            val socket = mmSocket
            socket ?: return
            socket.connect()
            // The connection attempt succeeded. Perform work associated with
            // the connection in a separate thread.
            manageMyConnectedSocket(socket)
        }

        // Closes the client socket and causes the thread to finish.
        fun cancel() {
            try {
                mmSocket?.close()
            } catch (e: IOException) {
                Log.e(TAG, "Could not close the client socket", e)
            }
        }
    }

    private inner class ConnectedThread(private val mmSocket: BluetoothSocket) : Thread() {

        private val mmInStream: InputStream = mmSocket.inputStream
        private val mmOutStream: OutputStream = mmSocket.outputStream
        // 受け取る文字列のサイズを1にします。1バイトで受け取るためです。
        private val mmBuffer: ByteArray = ByteArray(1)
        //変換した文字列の格納変数
        var str2 = ""

        override fun run() {
            var numBytes: Int // bytes returned from read()
            Log.d(TAG, "connect start!")
            // Keep listening to the InputStream until an exception occurs.
            while (true) {
                while(true){
                    numBytes = try {
                        mmInStream.read(mmBuffer)
                    } catch (e: IOException) {
                        Log.d(TAG, "Input stream was disconnected", e)
                        break
                    }
                    //改行した時
                    if(mmBuffer[0].toString()=="13") {
                        break
                    }
                    //,(カンマ)が送られた時
                    else if (mmBuffer[0].toString() == "44") {
                        break
                    }
                    //それ以外（数値や文字が送られてきたとき）
                    else {
                        //デコードに必要なキャラセットを作成
                        val charset = Charsets.UTF_8
                        //1バイトの情報を今まで受信してきた文字と組み合わせる（加算する）
                        //受信した1バイトの情報をUTF-8に変換　デコード操作
                        str2 += String(mmBuffer, charset)
                    }
                }
                // Logcatで表示
                Log.d(TAG,str2)
                // 表示した後に文字列変数を初期化
                str2=""
            }
        }


        // Call this method from the main activity to shut down the connection.
        fun cancel() {
            try {
                mmSocket.close()
            } catch (e: IOException) {
                Log.e(TAG, "Could not close the connect socket", e)
            }
        }
    }
}

```

## SelectActivity.kt
BLEデバイスの検索と選択をするActivityです。初めにファイルを作成していきます。
プロジェクトのMainActivity.ktがあるディレクトリにSelectActivity.ktファイルを作成してください。作成方法はMainActivity.ktの入っているフォルダを右クリックしてNew>Activity>Galleryを選択して、Empty Views ActivityをクリックしてNEXTを押します。
出てきたウインドウのにActivity Nameに**SelectActivity**と入力してFinishを押すと作成できます。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/0bc582ce-7b5b-3eed-6aa8-3e70758424f2.png)
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/c5939000-df25-6c1a-697c-39bbadc76044.png)

では、作成したファイルに以下のコードを書いてください。処理については後ほど説明します。

```SelectActivity.kt
//動作環境に合わせて変更してください
package com.mongodb.housemonitor

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.content.Intent
import android.util.Log
import android.widget.Button
import androidx.core.view.get
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import java.util.*
//動作環境に合わせて変更してください
import com.mongodb.housemonitor.ViewAdapter
import kotlinx.android.synthetic.main.item_view.*

const val TAG_s = "selectActivity"
var conn_device: BluetoothDevice?=null
var status:Int=0

class SelectActivity : AppCompatActivity(){
    private lateinit var recyclerView: RecyclerView
    private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()

    override fun onCreate(savedInstanceState: Bundle?){
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_select)
        val button: Button = findViewById(R.id.button)
        var pusta: MutableList<String> = ArrayList()
        var dede: MutableList<BluetoothDevice> = ArrayList()
        //val intent = Intent(this, MainActivity::class.java)
        if (bluetoothAdapter==null){
            Log.d(TAG_s, "ble is not sup")
            return
        }
        val pairedDevices: Set<BluetoothDevice> = bluetoothAdapter.getBondedDevices()
        if (pairedDevices.size>0){
            for (device in  pairedDevices){
                val deb = device.name
                dede.add(device)
                pusta.add(deb)
            }
        }
        recyclerView=findViewById(R.id.recyclerView)
        recyclerView.adapter = ViewAdapter(pusta)
        recyclerView.layoutManager = LinearLayoutManager(this)
        button.setOnClickListener {
            //intent.putExtra("po",status)
            conn_device = dede[status]
            finish()
        }
    }
}
```

また、上記処理の中に必要なレイアウトを実行するために必要なクラスを作成していきます。SelectActivity.ktと同様の場所に下記二つのkotlinクラスを作成して、内容をそのさらに下に記されたコードに書き変えてください。

* ViewAdapter.kt
* ViewHolder.kt

```ViewAdapter.kt
//動作環境に合わせて変更してください
package com.mongodb.housemonitor

import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import java.util.*

class ViewAdapter(val list: List<String>) : RecyclerView.Adapter<ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_view, parent, false)
        return ViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.positionText.text = position.toString()
        holder.titleText.text = list[position]
        holder.sButton.setOnClickListener {
            Log.d(TAG,position.toString())
            status = position
        }
    }
    override fun getItemCount(): Int = list.size
}
```
```ViewHolder.kt
//動作環境に合わせて変更してください
package com.mongodb.housemonitor

import android.view.View
import android.widget.Button
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val positionText: TextView = itemView.findViewById(R.id.position)
    val titleText: TextView = itemView.findViewById(R.id.title)
    val sButton: Button = itemView.findViewById(R.id.button)
}
```
上記2つのコードについては[【超初心者向け】Android入門 RecyclerView編](https://qiita.com/dosukoi_android/items/24ba411a02f4b6c3a447)を参考にさせていただきました。

次に、レイアウトファイルも作成していきます。SelectActivity.ktが作成されるとresフォルダのlayoutフォルダにactivity_select.xmlが作成されていると思います。
中身を下記のように変更してください。
```activity_select.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="400dp">
    </androidx.recyclerview.widget.RecyclerView>

    <Button
        android:id = "@+id/button"
        android:layout_width="120dp"
        android:layout_height="40dp"
        android:layout_gravity="center_horizontal"
        android:text = "Connect!"
        />
</LinearLayout>
```
さらにactivity_select.xmlと同じ場所にxmlファイルを新規作成して下記コードに書き変えてください。

```item_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="16dp">

    <TextView
        android:id="@+id/position"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:textColor="@android:color/black"
        android:textSize="22sp" />

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginStart="10dp"
        android:textColor="@android:color/black"
        android:textSize="22sp" />
    <Button
        android:id = "@+id/button"
        android:text="connect"
        android:layout_width="120dp"
        android:layout_height = "wrap_content"
        android:layout_gravity="end"
        />

</LinearLayout>
```

最後にmanifestファイルにSelectActivityを認識させます。
```AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mongodb.housemonitor">
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />

    <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.Housemonitor">
        <activity
            android:name=".SelectActivity"/>
        <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>
        </activity>
    </application>

</manifest>
```
```xml
<activity
            android:name=".SelectActivity"/>
```
上記コードを追記しました。これを追記しないと動かないそうです。本件は下記のリンクを参考にさせていただきました。詳細は下記を参考にしてください。
参考> [【超初心者向け】Android入門 画面遷移編](https://qiita.com/dosukoi_android/items/f0de78a98e1290dee9d2)

# 動作結果
上記ソースコードを実行すると初めに次のような画面が表示されます。私の場合BLEデバイスを2つペアリング設定していましたので0、１と2行分表示されています。

![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/c0b4d5c0-f57a-6c72-c570-834fa12a4658.png)
BLE接続するためには接続したいデバイスの行のCONNCETボタンを押してから、下部中央にあるCONNCET！ボタンを押します。[^2] BLEデバイスとの接続がされれば前回と同様にHello World！と書かれた画面に遷移して、Android Studio上で受信データが確認できるはずです。

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/47685cd3-a0f7-e0e5-0d0e-33f7ce16038f.png)


# ソースコードの解説
## 前回との差分 イメージ
初めに前回から追記した部分のイメージを簡単に説明します。

今回はスマホのペアリング設定済みのデバイスの中から接続先を選択する方式を取りたいと思います。[^3]そこでBLEデバイスを選択する操作をMainActivityとは別のSelectActivityというActivityを実行することとしました。

文字の説明だけでは差分が分かりづらいと思いますので、下図で全体のイメージを可視化します。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/19223877-631d-f034-a7a2-c61896335ada.png)
前回のプログラムでは`MainActivity`の`onStart()`で全て実行していましたが、それを分けている感じです。

## MainActivity⇒SelectActivityへの遷移
では細かくコードの内容を見ていきましょう。
前回のコードの差分としてはまず`MainActivity`の`onCreate()`です。
```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //レイアウトのactivity_mainはonStartで使用するためここでは記載しない
        //setContentView(R.layout.activity_main)
        val intent = Intent(this, SelectActivity::class.java)
        startActivity(intent)
    }
```
``val intent=``の行で`selectActivity`を定義して、次の行で実行しています。また、`onCreate()`ではactivity_main.xmlを実行しませんのでコメントアウトしています。

## SelectActivity
では`SelectActivity`の内容を説明していきます。初めに必要な変数を定義します。
下記のグローバル変数`conn_device`は`MainActivity`と`SelectActivity`で接続するBLEデバイスをやり取りするための変数です。この変数に接続したいBLEデバイスの情報を格納して`MainActivity`に渡して接続動作を行います。[^4]
次の`status`変数はBLEデバイスが選択状態の時にその選択した行を記憶する変数です。
```kotlin
var conn_device: BluetoothDevice?=null
var status:Int=0
```
次にclass内部に入って、`RecyclerView`変数を定義します。本変数はスマホに登録されているBLEデバイスの情報を**リスト**で表示するために必要なレイアウト用の変数です。次に`BluetoothAdapter?`変数についてはスマホがBluetoothを使用できるか確認するためのものです。
その後の`onCreate()`については使用するレイアウトファイル（activity_select.xml）を指定して必要な変数を用意しています。変数の意味は下記のとおりです。

* `button`：BLEデバイスの選択状態の時に、選択されたデバイスに接続するトリガーとなるボタンです。
* `pusta`：BLEデバイスの**名前情報のみ**を格納する変数です。レイアウトで表示するときにこの名前を使用します。
* `dede`：BLEデバイスのすべての情報を格納する変数です。

変数定義後のif文ではスマホがbluetoothを使用できるかを確認しています。使用できる場合は何もしませんが、使用不可の場合はアプリが終わりAndroid studio側で`ble is not sup`と表示されます。 
```kotlin
class SelectActivity : AppCompatActivity(){
    private lateinit var recyclerView: RecyclerView
    private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()

    override fun onCreate(savedInstanceState: Bundle?){
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_select)
        val button: Button = findViewById(R.id.button)
        var pusta: MutableList<String> = ArrayList()
        var dede: MutableList<BluetoothDevice> = ArrayList()
        //val intent = Intent(this, MainActivity::class.java)
        if (bluetoothAdapter==null){
            Log.d(TAG_s, "ble is not sup")
            return
        }
```
次の`pairDevices`変数からfor文ではスマホに登録されているBLEデバイスの情報を先ほど定義した`dede`と`pusta`に格納します。
その後`ViewAdapter`クラスに`pusta`を渡し、リサイクラービューを表示させます。
```kotlin
val pairedDevices: Set<BluetoothDevice> = bluetoothAdapter.getBondedDevices()
        if (pairedDevices.size>0){
            for (device in  pairedDevices){
                val deb = device.name
                dede.add(device)
                pusta.add(deb)
            }
        }
        recyclerView=findViewById(R.id.recyclerView)
        recyclerView.adapter = ViewAdapter(pusta)
        recyclerView.layoutManager = LinearLayoutManager(this)
```

## ViewAdapterとViewHolder
`ViewAdapter`では初めに`ViewHolder`クラスに表の一行分のレイアウトを作成させます。`ViewHolder`の中身は後述します。
`ViewHolder`のレイアウトをスマホがペアリング設定しているデバイス分作り出して表にします。レイアウトの設定はitem_view.xmlで設定しています。

`holder.sButton.setOnClickListener`は各行（各BLEデバイス）にあるボタンが押されたときに実行される動作です。押されると`SelectActivity`上で宣言したグローバル変数の`status`にデバイスを示す数字（行数）が格納されます。
```kotlin
class ViewAdapter(val list: List<String>) : RecyclerView.Adapter<ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_view, parent, false)
        return ViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.positionText.text = position.toString()
        holder.titleText.text = list[position]
        holder.sButton.setOnClickListener {
            //Log.d(TAG,position.toString())
            status = position
        }
    }
    override fun getItemCount(): Int = list.size
}
```
`ViewHolder`は前述したようにリストの一行分のレイアウトを表示するコードです。各変数については以下の通りです。
* `positionText`: 行数（0,1,2,3,,,）を示します。
* `titleText`: MainActivity上で取得したBLEデバイスの名前（`pasuta`変数）を元に表示します。
* `sButton`: 各BLEデバイス（行）に設定されるボタンです。このボタンを押すことで同じ行にあるBLEデバイスが選択された状態となります。選択状態でMainActivityのボタンを押すことで接続動作を開始できます（後述）。

```kotlin
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val positionText: TextView = itemView.findViewById(R.id.position)
    val titleText: TextView = itemView.findViewById(R.id.title)
    val sButton: Button = itemView.findViewById(R.id.button)
}
```
次に`onBindViewHolder`の中身ですが先ほど定義したsButtonを押すと下記の操作が実行されます。グローバル変数の`status`に`position`変数、つまり行番号を代入します。
```kotlin
        holder.sButton.setOnClickListener {
            //Log.d(TAG,position.toString())
            status = position
        }
```

## 接続先決定とSelectActivtyの終了
`SelectActivity`に戻り、最後のボタンの動作です。ボタンが押されると下記の`setOnClickListener`の中身が実行されます。内容としては前述したグローバル変数である`conn_device`に`status`番目のBLEデバイスの情報が格納されます。つまり、選択したデバイスが`conn_device`変数に格納されます。
そして`finish()`で`SelectActivity`を終了します。
```kotlin
button.setOnClickListener {
            //intent.putExtra("po",status)
            conn_device = dede[status]
            finish()
        }
```
終了後、`MainActivity`の`onStart()`に入ります。`onStart()`では`MainActivity`用のレイアウトを実行します。次に`connectThread(device)`で`SelectActivity`で選択したBLEデバイスを引数に入れて接続作業に入ります。ここから先は前回の記事の内容と同じですので説明は省略します。
```kotlin
override fun onStart() {
        super.onStart()
        setContentView(R.layout.activity_main)
        connectThread = ConnectThread(conn_device)
        connectThread?.start()
    }
```

## MainActivityの一部変更点
`MainActivity`の一部前回と異なる点を下に示しておきます。`SelectActivity`上でBLEデバイスの変数である` conn_device: BluetoothDevice?`を宣言しましたが、前回とは違い宣言時点で接続先のデバイスが決定していないため方に`?`があります。この変更に合わせて下記の部分で`?`を追記しています。
```kotlin
    private inner class ConnectThread(device: BluetoothDevice?)
```

```kotlin
    private inner class ConnectThread(device: BluetoothDevice?) : Thread() {
        private val mmSocket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) {
            device?.createInsecureRfcommSocketToServiceRecord(device.uuids[0].uuid)
        }
```

## レイアウトと変数の対応について
ここまで様々なレイアウトに関する変数を定義していましたが、どの変数がどのレイアウトに対応しているかが分かりづらいと思いましたので下図に示します。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/c079fa04-0897-c5d0-05cf-52746bce4add.png)

# まとめ
これで任意のBLEデバイスをアプリ上で選択して接続できます。今回の記事の目的としては単純に動かせるものを作ることでしたので、レイアウトについては参考資料を参考にしつつ、要件に応じて足したり引いたりしました。作成する際には皆さまもオリジナリティを出して修正・作成してみてください。

執筆する前はそこまで深い内容にならないだろうと思っていたのですが、3週間ほど時間がかかってしまいました。また、前回からだいぶ日が経ってしまったのでAndroid studioの環境も変わっており、そこの学習も大変でした。

次回は受信データを適用したレイアウトを作成していきます、、がちょっと別のネタを公開していきますのでだいぶ後になるかもしれません。気長に待っていただければ幸いです。

もし内容に関して不備、間違い、不適切な点ありましたらコメント欄でご連絡いただければ幸いです。まだまだ勉強中ですので至らない点多々あると思いますがよろしくお願いします！！

# 参考文献、サイトまとめ
* [【超初心者向け】Android入門 RecyclerView編](https://qiita.com/dosukoi_android/items/24ba411a02f4b6c3a447) 
レイアウトのリスト作成とても参考になりました。リストの仕組みやレイアウトについてはこちらを参照いただければと思います。
* [【超初心者向け】Android入門 画面遷移編](https://qiita.com/dosukoi_android/items/f0de78a98e1290dee9d2)
こちらも別のActivityを起動させる、遷移させる機能についてとても参考になりました。上記同様にActivity関係の操作についてはこちらを参照いただければと思います。
* [【android】ActivityからActivityの画面遷移](https://qiita.com/Tabito/items/b6976a17d55b05c9d743)
* https://adsaria.hatenadiary.org/entry/20110428/1303966837
* [知らずに作って大丈夫？Androidの基本的なライフサイクルイベント31選](https://atmarkit.itmedia.co.jp/ait/articles/1604/04/news011_2.html)

# IoTシリーズ一覧
* [Arduinoとスマホでお家をモニタ【IoTシステム構築紹介＆Arduino＋Bluetooth編】](https://qiita.com/Antareskkudo/items/f80b74151e56759d6c67)
* [Arduinoとスマホでお家をモニタPart2【スマホで情報を受信！】](https://qiita.com/Antareskkudo/items/e102d5c4aebff21766ea)

[^1]: 本記事の目的はこのシリーズの目的とは少しずれますし内容も前回や前々回と比較して薄くなっていますのでPart2.5としています。
[^2]: ボタンの表記の仕方が分かりづらいですね（笑）。必要に応じてFixしてみてください。
[^3]: [前回](https://qiita.com/Antareskkudo/items/e102d5c4aebff21766ea)の記事ではRN-42をペアリング設定しました。そのため、今回のケースではペアリング設定済みのデバイスから選択する方式としました。
[^4]: グローバル変数でActivity間のやり取りをするのはあまり推奨しない場合があります。今回は難しいことを気にせずに**単純に動かすため**、一番Activity間の変数のやり取りが簡単な方法を選びました。必要に応じてFixしてください。