

# IVS 聊天用戶端傳訊 SDK：Android 版教學課程第 1 部分：聊天室
<a name="chat-sdk-android-tutorial-chat-rooms"></a>

這是由兩部分組成的教學課程的第一部分。透過使用 [Kotlin](https://kotlinlang.org/) 程式設計語言建置功能完整的 Android 應用程式，您將學習使用 Amazon IVS 聊天功能傳訊 SDK 的基礎知識。我們稱呼該應用程式為 *Chatterbox*。

在開始該模組之前，請花幾分鐘時間熟悉先決條件、聊天權杖背後的重要概念以及建立聊天室所需的後端伺服器。

這些教學課程專為經驗豐富的 Android 開發人員而建立，他們不熟悉 IVS 聊天功能傳訊 SDK。您將需要熟悉 Kotlin 程式設計語言並在 Android 平台上建立 UI。

本教學課程的第一部分分為幾個部分：

1. [設定本機身分驗證/授權伺服器](#chat-android-rooms-auth-server)

1. [建立 Chatterbox 專案](#chat-android-rooms-chatterbox)

1. [連線到聊天室並觀察連線更新](#chat-android-rooms-connect-state)

1. [建立字符提供者](#chat-android-rooms-token-provider)

1. [後續步驟](#chat-android-rooms-next-steps)

如需完整的 SDK 文件，請先閱讀 [Amazon IVS 聊天用戶端傳訊 SDK](chat-sdk.md) (載於《Amazon IVS 聊天功能使用者指南**》中) 和 [Chat Client Messaging: SDK for Android Reference](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/) (聊天用戶端傳訊：Android 版 SDK 參考) (位於 GitHub 上)。

## 必要條件
<a name="chat-android-rooms-prerequisites"></a>
+ 熟悉 Kotlin 並在 Android 平台上建立應用程式。如果您不熟悉如何為 Android 建立應用程式，請在適用於 Android 開發人員的[建置您的第一個應用程式](https://developer.android.com/codelabs/basic-android-kotlin-compose-first-app#0)指南中了解基礎知識。
+ 仔細閱讀並理解 [Amazon IVS 聊天功能入門](getting-started-chat.md)。
+ 使用現有 IAM 政策中定義的 `CreateChatToken` 和 `CreateRoom` 功能建立 AWS IAM 使用者。(請參閱 [Amazon IVS 聊天功能入門](getting-started-chat.md))。
+ 確保將此使用者的私密/存取金鑰儲存在 AWS 憑證檔案中。如需指示，請參閱《[AWS CLI 使用者指南](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)》(特別是[組態和憑證檔案設定](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html))。
+ 建立聊天室並保存其 ARN。請參閱 [Amazon IVS 聊天功能入門](getting-started-chat.md)。(如果您未保存該 ARN，稍後可以使用主控台或 Chat API 來查詢。)

## 設定本機身分驗證/授權伺服器
<a name="chat-android-rooms-auth-server"></a>

後端伺服器負責建立聊天室並產生 IVS 聊天功能 Android SDK 需要的聊天權杖，以便對聊天室的用戶端執行身分驗證和授權。

請參閱 *Amazon IVS 聊天功能入門*中的[建立聊天字符](getting-started-chat-auth.md)。如流程圖所示，您的伺服器端程式碼會負責建立聊天權杖。這意味著應用程式必須透過從伺服器端應用程式請求聊天字符，來提供自己產生聊天字符的方法。

我們使用 [Ktor](https://ktor.io/) 架構建立即時本機伺服器，以管理使用本機 AWS 環境建立聊天權杖的作業。

此時，希望您已正確設定 AWS 憑證。如需逐步說明，請參閱[設定適用於開發的 AWS 憑證和區域](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html)。

建立新目錄並將其命名為 `chatterbox`，然後在其內部再建立另一個名為 `auth-server` 的目錄。

伺服器資料夾的結構如下：

```
- auth-server
  - src
    - main
      - kotlin
        - com
          - chatterbox
            - authserver
              - Application.kt
       - resources
         - application.conf
         - logback.xml
   - build.gradle.kts
```

*注意：您可以直接將這裡的程式碼複製/貼上到參考的檔案中。*

接下來，我們會新增所有必要的相依性和外掛程式，以使 auth 伺服器正常工作：

**Kotlin 指令碼**：

```
// ./auth-server/build.gradle.kts

plugins {
   application
   kotlin("jvm")
   kotlin("plugin.serialization").version("1.7.10")
}

application {
   mainClass.set("io.ktor.server.netty.EngineMain")
}

dependencies {
   implementation("software.amazon.awssdk:ivschat:2.18.1")
   implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20")

   implementation("io.ktor:ktor-server-core:2.1.3")
   implementation("io.ktor:ktor-server-netty:2.1.3")
   implementation("io.ktor:ktor-server-content-negotiation:2.1.3")
   implementation("io.ktor:ktor-serialization-kotlinx-json:2.1.3")

   implementation("ch.qos.logback:logback-classic:1.4.4")
}
```

現在，我們需要為 auth 伺服器設定記錄功能。(如需詳細資訊，請參閱[設定記錄器](https://ktor.io/docs/logging.html#configure-logger))。

**XML**：

```
// ./auth-server/src/main/resources/logback.xml

<configuration>
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
      <encoder>
         <pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
      </encoder>
   </appender>
   <root level="trace">
      <appender-ref ref="STDOUT"/>
   </root>
   <logger name="org.eclipse.jetty" level="INFO"/>
   <logger name="io.netty" level="INFO"/>
</configuration>
```

[Ktor](https://ktor.io/docs/welcome.html) 伺服器需要組態設定，其會自動從 `resources` 目錄中的 `application.*` 檔案中載入，因此我們也會新增這些項目。(如需詳細資訊，請參閱[檔案中的組態](https://ktor.io/docs/configurations.html#configuration-file)。)

**HOCON**：

```
// ./auth-server/src/main/resources/application.conf

ktor {
   deployment {
      port = 3000
   }
   application {
      modules = [ com.chatterbox.authserver.ApplicationKt.main ]
   }
}
```

最後，讓我們來實作伺服器：

**Kotlin**：

```
// ./auth-server/src/main/kotlin/com/chatterbox/authserver/Application.kt

package com.chatterbox.authserver

import io.ktor.http.*
import io.ktor.serialization.kotlinx.json.*
import io.ktor.server.application.*
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import software.amazon.awssdk.services.ivschat.IvschatClient
import software.amazon.awssdk.services.ivschat.model.CreateChatTokenRequest

@Serializable
data class ChatTokenParams(var userId: String, var roomIdentifier: String)

@Serializable
data class ChatToken(
   val token: String,
   val sessionExpirationTime: String,
   val tokenExpirationTime: String,
)

fun Application.main() {
   install(ContentNegotiation) {
      json(Json)
   }

   routing {
      post("/create_chat_token") {
         val callParameters = call.receive<ChatTokenParams>()
         val request = CreateChatTokenRequest.builder().roomIdentifier(callParameters.roomIdentifier)
            .userId(callParameters.userId).build()
         val token = IvschatClient.create()
            .createChatToken(request)

         call.respond(
            ChatToken(
                token.token(),
                token.sessionExpirationTime().toString(),
                token.tokenExpirationTime().toString()
            )
         )
      }
   }
}
```

## 建立 Chatterbox 專案
<a name="chat-android-rooms-chatterbox"></a>

若要建立 Android 專案，請安裝並開啟 [Android Studio](https://developer.android.com/studio)。

請按照 Android 官方[建立專案指南](https://developer.android.com/studio/projects/create-project)中列出的步驟進行操作。
+ 在[選擇專案類型](https://developer.android.com/studio/projects/create-project)中，為 Chatterbox 應用程式選擇**空活動**專案範本。
+ 在[設定專案](https://developer.android.com/studio/projects/create-project#configure)中，為組態欄位選擇下列值：
  + **名稱**：My App
  + **套件名稱**：com.chatterbox.myapp
  + **儲存位置**：指向上一步中建立的 `chatterbox` 目錄
  + **語言**：Kotlin
  + **API 最低等級**：API 21：Android 5.0 (Lollipop)

正確指定所有組態參數後，`chatterbox` 資料夾內的檔案結構應如下所示：

```
- app
  - build.gradle
  ...
- gradle
- .gitignore
- build.gradle
- gradle.properties
- gradlew
- gradlew.bat
- local.properties
- settings.gradle
- auth-server
  - src
    - main
      - kotlin
        - com
          - chatterbox
            - authserver
              - Application.kt
       - resources
         - application.conf
         - logback.xml
   - build.gradle.kts
```

現在有一個正在運行的 Android 專案，我們就可以將 [com.amazonaws:ivs-chat-messaging](https://mvnrepository.com/artifact/com.amazonaws/ivs-chat-messaging) 新增至 `build.gradle` 相依性。(有關 [Gradle](https://gradle.org/) 建置工具包的詳細資訊，請參閱[設定您的建置](https://developer.android.com/build)。)

**注意**：在每個程式碼片段的頂部，都有一個路徑，指向專案內您應該正在其中進行變更的檔案。這是專案根路徑的相對路徑。

*在下面的程式碼中，將 `<version>` 取代為 Android 版聊天 SDK 的最新版本號 (例如，1.0.0)*。

**Kotlin**：

```
// ./app/build.gradle

plugins {
// ...
}

android {
// ...
}

dependencies {
   implementation("com.amazonaws:ivs-chat-messaging:<version>")
// ...
}
```

新增新的相依性之後，在 Android Studio 中執行**將專案與 Gradle 檔案同步**，以便將專案與新的相依性同步。(如需詳細資訊，請參閱[新增建置相依性](https://developer.android.com/build/dependencies)。)

為了方便地從專案根目錄中執行 auth 伺服器 (在上一節中建立)，我們將其作為新模組包含在 `settings.gradle` 中。(如需詳細資訊，請參閱[使用 Gradle 建構和建置軟體元件](https://docs.gradle.org/current/userguide/multi_project_builds.html)。)

**Kotlin 指令碼**：

```
// ./settings.gradle

// ...

rootProject.name = "Chatterbox"
include ':app'
include ':auth-server'
```

從現在開始，由於 `auth-server` 包含在 Android 專案中，所以您可以使用下列命令從專案的根目錄中執行 auth 伺服器：

**Shell**：

```
./gradlew :auth-server:run
```

## 連線到聊天室並觀察連線更新
<a name="chat-android-rooms-connect-state"></a>

若要開啟聊天室連線，我們會使用 [onCreate() 活動生命週期回呼](https://developer.android.com/guide/components/activities/activity-lifecycle)，它在首次建立活動時觸發。[ChatRoom 建構函數](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/-amazon%20-i-v-s%20-chat%20-messaging%20-s-d-k%20for%20-android/com.amazonaws.ivs.chat.messaging/-chat-room/index.html)要求我們提供 `region` 和 `tokenProvider` 來執行個體化聊天室連線。

**注意**：將在[下一節](#chat-android-rooms-token-provider)中實作下面程式碼片段中的 `fetchChatToken` 函數。

**Kotlin**：

```
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt

package com.chatterbox.myapp

// ...
import androidx.appcompat.app.AppCompatActivity
// ...

// AWS region of the room that was created in Getting Started with Amazon IVS Chat
const val REGION = "us-west-2"

class MainActivity : AppCompatActivity() {
    private var room: ChatRoom? = null
    // ...

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

      // Create room instance
      room = ChatRoom(REGION, ::fetchChatToken)
   }

// ...
}
```

顯示聊天室連線的變化並做出反應是構建諸如 `chatterbox` 聊天應用程式的重要部分。在開始與聊天室互動之前，我們必須訂閱聊天室連線狀態事件，以獲取更新。

[ChatRoom](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/-amazon%20-i-v-s%20-chat%20-messaging%20-s-d-k%20for%20-android/com.amazonaws.ivs.chat.messaging/-chat-room/index.html) 期望我們連接 [ChatRoomListener 介面](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/-amazon%20-i-v-s%20-chat%20-messaging%20-s-d-k%20for%20-android/com.amazonaws.ivs.chat.messaging/-chat-room/listener.html)實作來引發生命週期事件。目前，接聽程式函數在被叫用時只會記錄確認訊息：

**Kotlin**：

```
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt

// ...
package com.chatterbox.myapp
// ...
const val TAG = "IVSChat-App"

class MainActivity : AppCompatActivity() {
// ...

    private val roomListener = object : ChatRoomListener {
        override fun onConnecting(room: ChatRoom) {
            Log.d(TAG, "onConnecting")
        }

        override fun onConnected(room: ChatRoom) {
            Log.d(TAG, "onConnected")
        }

        override fun onDisconnected(room: ChatRoom, reason: DisconnectReason) {
            Log.d(TAG, "onDisconnected $reason")
        }

        override fun onMessageReceived(room: ChatRoom, message: ChatMessage) {
            Log.d(TAG, "onMessageReceived $message")
        }

        override fun onMessageDeleted(room: ChatRoom, event: DeleteMessageEvent) {
            Log.d(TAG, "onMessageDeleted $event")
        }

        override fun onEventReceived(room: ChatRoom, event: ChatEvent) {
            Log.d(TAG, "onEventReceived $event")
        }

        override fun onUserDisconnected(room: ChatRoom, event:    DisconnectUserEvent) {
            Log.d(TAG, "onUserDisconnected $event")
        }
    }
}
```

現在已實作 `ChatRoomListener`，我們可將其連接至聊天室執行個體：

**Kotlin**：

```
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt

package com.chatterbox.myapp
// ...

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   binding = ActivityMainBinding.inflate(layoutInflater)
   setContentView(binding.root)

   // Create room instance
   room = ChatRoom(REGION, ::fetchChatToken).apply {
      listener = roomListener
   }
}

private val roomListener = object : ChatRoomListener {
// ...
}
```

接下來，我們需要能夠讀取聊天室連線狀態。我們將其保留在 `MainActivity.kt` [屬性](https://kotlinlang.org/docs/properties.html)中，並將其初始化為聊天室的預設 DISCONNECTED 狀態 (請參閱[《IVS 聊天功能 Android 版 SDK 參考》](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/latest/)中的 `ChatRoom state`)。為了能夠使本機狀態保持最新，我們需要實作一個狀態更新程式函數；我們稱之為 `updateConnectionState`：

**Kotlin**：

```
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt

package com.chatterbox.myapp
// ...

enum class ConnectionState {
   CONNECTED,
   DISCONNECTED,
   LOADING
}

class MainActivity : AppCompatActivity() {
   private var connectionState = ConnectionState.DISCONNECTED
// ...

   private fun updateConnectionState(state: ConnectionState) {
      connectionState = state

      when (state) {
         ConnectionState.CONNECTED -> {
            Log.d(TAG, "room connected")
         }
         ConnectionState.DISCONNECTED -> {
            Log.d(TAG, "room disconnected")
         }
         ConnectionState.LOADING -> {
            Log.d(TAG, "room loading")
         }
      }
   }
}
```

接下來，將我們的狀態更新程式函數與 [ChatRoom.listener](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/-amazon%20-i-v-s%20-chat%20-messaging%20-s-d-k%20for%20-android/com.amazonaws.ivs.chat.messaging/-chat-room/listener.html) 屬性整合在一起：

**Kotlin**：

```
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt

package com.chatterbox.myapp
// ...

class MainActivity : AppCompatActivity() {
// ...

   private val roomListener = object : ChatRoomListener {
      override fun onConnecting(room: ChatRoom) {
         Log.d(TAG, "onConnecting")
         runOnUiThread {
            updateConnectionState(ConnectionState.LOADING)
         }
      }

      override fun onConnected(room: ChatRoom) {
         Log.d(TAG, "onConnected")
         runOnUiThread {
            updateConnectionState(ConnectionState.CONNECTED)
         }
      }

      override fun onDisconnected(room: ChatRoom, reason: DisconnectReason) {
         Log.d(TAG, "[${Thread.currentThread().name}] onDisconnected")
         runOnUiThread {
            updateConnectionState(ConnectionState.DISCONNECTED)
         }
      }
   }
}
```

現在我們能夠儲存、接聽 [ChatRoom](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/-amazon%20-i-v-s%20-chat%20-messaging%20-s-d-k%20for%20-android/com.amazonaws.ivs.chat.messaging/-chat-room/index.html) 狀態更新並做出反應，因此可以初始化連線：

**Kotlin**：

```
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt

package com.chatterbox.myapp
// ...

enum class ConnectionState {
   CONNECTED,
   DISCONNECTED,
   LOADING
}

class MainActivity : AppCompatActivity() {
   private var connectionState = ConnectionState.DISCONNECTED
// ...

   private fun connect() {
      try {
         room?.connect()
      } catch (ex: Exception) {
         Log.e(TAG, "Error while calling connect()", ex)
      }
   }

   private val roomListener = object : ChatRoomListener {
      // ...
      override fun onConnecting(room: ChatRoom) {
         Log.d(TAG, "onConnecting")
         runOnUiThread {
            updateConnectionState(ConnectionState.LOADING)
         }
      }

      override fun onConnected(room: ChatRoom) {
         Log.d(TAG, "onConnected")
         runOnUiThread {
            updateConnectionState(ConnectionState.CONNECTED)
         }
      }
      // ...
   }
}
```

## 建立字符提供者
<a name="chat-android-rooms-token-provider"></a>

現在可建立一個函數，其負責在我們的應用程式中建立和管理聊天權杖。在此範例中，我們使用[適用於 Android 的 Retrofit HTTP 用戶端](https://square.github.io/retrofit/)。

在傳送任何網路流量之前，我們必須為 Android 設定網路安全組態。(如需詳細資訊，請參閱[網路安全組態](https://developer.android.com/privacy-and-security/security-config)。) 我們首先向 [App Manifest](https://developer.android.com/guide/topics/manifest/manifest-intro) 檔案新增網路許可。請注意，已新增 `user-permission` 標籤和 `networkSecurityConfig` 屬性，這將指向新網路安全組態。*在下面的程式碼中，將 `<version>` 取代為 Android 版聊天 SDK 的最新版本號 (例如，1.0.0)*。

**XML**：

```
// ./app/src/main/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.chatterbox.myapp">
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:allowBackup="true"
        android:fullBackupContent="@xml/backup_rules"
        android:label="@string/app_name"
        android:networkSecurityConfig="@xml/network_security_config"
// ...

// ./app/build.gradle


dependencies {
   implementation("com.amazonaws:ivs-chat-messaging:<version>")
// ...

   implementation("com.squareup.retrofit2:retrofit:2.9.0")
}
```

聲明 `10.0.2.2` 和 `localhost` 域為可信域，開始與我們的後端交換訊息：

**XML**：

```
// ./app/src/main/res/xml/network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">10.0.2.2</domain>
        <domain includeSubdomains="true">localhost</domain>
    </domain-config>
</network-security-config>
```

接下來，我們需要新增一個新的相依性，並[新增 Gson 轉換器](https://github.com/square/retrofit/tree/trunk/retrofit-converters/gson)以用於解析 HTTP 回應。*在下面的程式碼中，將 `<version>` 取代為 Android 版聊天 SDK 的最新版本號 (例如，1.0.0)*。

**Kotlin 指令碼**：

```
// ./app/build.gradle

dependencies {
   implementation("com.amazonaws:ivs-chat-messaging:<version>")
// ...

   implementation("com.squareup.retrofit2:retrofit:2.9.0")
}
```

若要擷取聊天權杖，需要從 `chatterbox` 應用程式中發出 POST HTTP 請求。我們在一個介面中定義請求，以便 Retrofit 能夠實作。(請參閱 [Retrofit 文件](https://square.github.io/retrofit/)，也請熟悉 [CreateChatToken](https://docs.aws.amazon.com//ivs/latest/ChatAPIReference/API_CreateChatToken.html#API_CreateChatToken_RequestBody) 操作規範。)

**Kotlin**：

```
// ./app/src/main/java/com/chatterbox/myapp/network/ApiService.kt

package com.chatterbox.myapp.network
// ...


import androidx.annotation.Keep
import com.amazonaws.ivs.chat.messaging.ChatToken
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.POST

data class CreateTokenParams(var userId: String, var roomIdentifier: String)

interface ApiService {
   @POST("create_chat_token")
   fun createChatToken(@Body params: CreateTokenParams): Call<ChatToken>
}
```

現在，透過網路設定，可以新增一個負責建立和管理聊天權杖的函數。我們將其新增至 `MainActivity.kt`，其會在[產生](#chat-android-rooms-chatterbox)專案時自動建立：

**Kotlin**：

```
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt


package com.chatterbox.myapp

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.amazonaws.ivs.chat.messaging.*
import com.chatterbox.myapp.network.CreateTokenParams
import com.chatterbox.myapp.network.RetrofitFactory
import retrofit2.Call
import java.io.IOException
import retrofit2.Callback
import retrofit2.Response

// custom tag for logging purposes
const val TAG = "IVSChat-App"

// any ID to be associated with auth token
const val USER_ID = "test user id"
// ID of the room the app wants to access. Must be an ARN. See Amazon Resource Names(ARNs)
const val ROOM_ID = "arn:aws:..."
// AWS region of the room that was created in Getting Started with Amazon IVS Chat
const val REGION = "us-west-2"

class MainActivity : AppCompatActivity() {
   private val service = RetrofitFactory.makeRetrofitService()
   private lateinit var userId: String

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

   private fun fetchChatToken(callback: ChatTokenCallback) {
      val params = CreateTokenParams(userId, ROOM_ID)
      service.createChatToken(params).enqueue(object : Callback<ChatToken> {
         override fun onResponse(call: Call<ChatToken>, response: Response<ChatToken>) {
            val token = response.body()
            if (token == null) {
               Log.e(TAG, "Received empty token response")
               callback.onFailure(IOException("Empty token response"))
               return
            }

            Log.d(TAG, "Received token response $token")
            callback.onSuccess(token)
         }

         override fun onFailure(call: Call<ChatToken>, throwable: Throwable) {
            Log.e(TAG, "Failed to fetch token", throwable)
            callback.onFailure(throwable)
         }
      })
   }
}
```

## 後續步驟
<a name="chat-android-rooms-next-steps"></a>

現在您已經建立聊天室連線，請繼續本 Android 版教學課程的第 2 部分：[訊息和事件](chat-sdk-android-tutorial-messages-events.md)。