สร้างแอปรับส่งข้อความสำหรับ Android Auto

หมวดหมู่การสื่อสารจะพร้อมใช้งานเร็วๆ นี้
เรากำลังขยายหมวดหมู่การรับส่งข้อความให้รองรับความสามารถใหม่ๆ รวมถึงประวัติข้อความและประสบการณ์การโทร

การติดต่อสื่อสารผ่านข้อความเป็นสิ่งที่สำคัญสำหรับคนขับหลายราย แอปแชทช่วยให้ผู้ใช้ทราบได้ว่าต้องไปรับบุตรหลานหรือมีการเปลี่ยนแปลงสถานที่ทานอาหารเย็นหรือไม่ เฟรมเวิร์ก Android ช่วยให้แอปรับส่งข้อความขยายบริการของตนไปยังประสบการณ์การขับขี่ได้โดยใช้อินเทอร์เฟซผู้ใช้มาตรฐานที่ช่วยให้ผู้ขับขี่ไม่ต้องละสายตาจากถนน

แอปที่รองรับการรับส่งข้อความสามารถขยายการแจ้งเตือนการรับส่งข้อความเพื่อให้ Android Auto แสดงการแจ้งเตือนเหล่านั้นได้เมื่อ Auto ทำงานอยู่ การแจ้งเตือนเหล่านี้จะแสดงในโหมดอัตโนมัติและช่วยให้ผู้ใช้อ่านและตอบกลับข้อความได้ในอินเทอร์เฟซที่สอดคล้องกันและรบกวนสายตาน้อย และเมื่อใช้ MessagingStyle API คุณจะได้รับการแจ้งเตือนข้อความที่เพิ่มประสิทธิภาพสำหรับอุปกรณ์ Android ทั้งหมด รวมถึง Android Auto การเพิ่มประสิทธิภาพนี้รวมถึง UI ที่ออกแบบมาโดยเฉพาะสำหรับการแจ้งเตือนข้อความ ภาพเคลื่อนไหวที่ปรับปรุงใหม่ และรองรับรูปภาพในบรรทัด

คู่มือนี้จะแสดงวิธีขยายแอปที่แสดงข้อความต่อผู้ใช้และรับการตอบกลับของผู้ใช้ เช่น แอปแชท เพื่อส่งต่อการแสดงข้อความและใบตอบกลับไปยังอุปกรณ์ Auto ดูคำแนะนำการออกแบบที่เกี่ยวข้องได้ที่แอปรับส่งข้อความในเว็บไซต์ Design for Driving

เริ่มต้นใช้งาน

หากต้องการให้บริการการรับส่งข้อความสำหรับอุปกรณ์ Auto แอปของคุณต้องประกาศการรองรับ Android Auto ในไฟล์ Manifest และสามารถทําสิ่งต่อไปนี้ได้

  • สร้างและส่งออบเจ็กต์ NotificationCompat.MessagingStyle ที่มีออบเจ็กต์การตอบกลับและการทำเครื่องหมายว่าอ่านแล้ว Action
  • จัดการการตอบกลับและทำเครื่องหมายการสนทนาว่าอ่านแล้วด้วย Service

แนวคิดและวัตถุ

ก่อนเริ่มออกแบบแอป คุณควรทำความเข้าใจวิธีที่ Android Auto จัดการการรับส่งข้อความ

การสื่อสารแต่ละกลุ่มเรียกว่าข้อความและแสดงโดยคลาส MessagingStyle.Message ข้อความประกอบด้วยผู้ส่ง เนื้อหาข้อความ และเวลาที่ส่งข้อความ

การสื่อสารระหว่างผู้ใช้เรียกว่าการสนทนาและแสดงโดยออบเจ็กต์ MessagingStyle การสนทนาหรือ MessagingStyle ประกอบด้วยชื่อ ข้อความ และข้อมูลว่าการสนทนาเกิดขึ้นในกลุ่มผู้ใช้หรือไม่

หากต้องการแจ้งให้ผู้ใช้ทราบถึงการอัปเดตการสนทนา เช่น ข้อความใหม่ แอปจะโพสต์ Notification ไปยังระบบ Android Notification นี้ใช้ออบเจ็กต์ MessagingStyle เพื่อแสดง UI สำหรับการรับส่งข้อความโดยเฉพาะในหน้าต่างแจ้งเตือน แพลตฟอร์ม Android จะส่ง Notification นี้ไปยัง Android Auto ด้วย และระบบจะดึงข้อมูล MessagingStyle ออกมาเพื่อโพสต์การแจ้งเตือนผ่านจอแสดงผลของรถ

นอกจากนี้ Android Auto ยังกำหนดให้แอปเพิ่มออบเจ็กต์ Action ลงใน Notification เพื่อให้ผู้ใช้ตอบกลับข้อความหรือทำเครื่องหมายว่าอ่านแล้วได้อย่างรวดเร็วจากแผงการแจ้งเตือนโดยตรง

กล่าวโดยสรุปคือ การสนทนาเดียวจะแสดงด้วยออบเจ็กต์ Notification ที่ปรับแต่งสไตล์ด้วยออบเจ็กต์ MessagingStyle MessagingStyle มีข้อความทั้งหมดในการสนทนานั้นในออบเจ็กต์ MessagingStyle.Message อย่างน้อย 1 รายการ และแอปต้องแนบออบเจ็กต์การตอบกลับและการทำเครื่องหมายว่าอ่านแล้ว Action กับ Notification เพื่อให้เป็นไปตามข้อกำหนดของ Android Auto

ขั้นตอนการรับส่งข้อความ

ส่วนนี้จะอธิบายขั้นตอนการรับส่งข้อความทั่วไประหว่างแอปของคุณกับ Android Auto

  1. แอปของคุณได้รับข้อความ
  2. แอปของคุณสร้างการแจ้งเตือน MessagingStyle ที่มีออบเจ็กต์การตอบกลับและการทำเครื่องหมายว่าอ่านแล้ว Action
  3. Android Auto ได้รับเหตุการณ์ "การแจ้งเตือนใหม่" จากระบบ Android และค้นหา MessagingStyle, ตอบกลับ Action และทําเครื่องหมายว่าอ่านแล้ว Action
  4. Android Auto จะสร้างและแสดงการแจ้งเตือนในรถ
  5. หากผู้ใช้แตะการแจ้งเตือนบนจอแสดงผลของรถ Android Auto จะทริกเกอร์การทําเครื่องหมายว่าอ่านแล้ว Action
    • แอปของคุณต้องจัดการเหตุการณ์ "ทำเครื่องหมายว่าอ่านแล้ว" นี้ในเบื้องหลัง
  6. หากผู้ใช้ตอบกลับการแจ้งเตือนด้วยเสียง Android Auto จะใส่ข้อความถอดเสียงคำตอบของผู้ใช้ลงในข้อความตอบกลับ Action แล้วเรียกให้ข้อความตอบกลับแสดง
    • แอปของคุณต้องจัดการเหตุการณ์การตอบกลับนี้ในเบื้องหลัง

สมมติฐานเบื้องต้น

หน้านี้ไม่ได้แนะนำการสร้างแอปรับส่งข้อความทั้งแอป ตัวอย่างโค้ดต่อไปนี้แสดงสิ่งที่แอปของคุณต้องมีก่อนจะเริ่มรองรับการรับส่งข้อความด้วย Android Auto

data class YourAppConversation(
        val id: Int,
        val title: String,
        val recipients: MutableList<YourAppUser>,
        val icon: Bitmap) {
    companion object {
        /** Fetches [YourAppConversation] by its [id]. */
        fun getById(id: Int): YourAppConversation = // ...
    }

    /** Replies to this conversation with the given [message]. */
    fun reply(message: String) {}

    /** Marks this conversation as read. */
    fun markAsRead() {}

    /** Retrieves all unread messages from this conversation. */
    fun getUnreadMessages(): List<YourAppMessage> { return /* ... */ }
}
data class YourAppUser(val id: Int, val name: String, val icon: Uri)
data class YourAppMessage(
    val id: Int,
    val sender: YourAppUser,
    val body: String,
    val timeReceived: Long)

ประกาศการรองรับ Android Auto

เมื่อ Android Auto ได้รับการแจ้งเตือนจากแอปรับส่งข้อความ ระบบจะตรวจสอบว่าแอปได้ประกาศรองรับ Android Auto หรือไม่ หากต้องการเปิดใช้การรองรับนี้ ให้ใส่รายการต่อไปนี้ในไฟล์ Manifest ของแอป

<application>
    ...
    <meta-data
        android:name="com.google.android.gms.car.application"
        android:resource="@xml/automotive_app_desc"/>
    ...
</application>

รายการไฟล์ Manifest นี้อ้างอิงถึงไฟล์ XML อื่นที่คุณต้องสร้างซึ่งมีเส้นทางต่อไปนี้ YourAppProject/app/src/main/res/xml/automotive_app_desc.xml ใน automotive_app_desc.xml ให้ประกาศความสามารถของ Android Auto ที่แอปรองรับ เช่น หากต้องการประกาศการรองรับการแจ้งเตือน ให้ใส่ข้อมูลต่อไปนี้

<automotiveApp>
    <uses name="notification" />
</automotiveApp>

หากแอปสามารถตั้งค่าเป็นตัวแฮนเดิล SMS เริ่มต้นได้ ให้ตรวจสอบว่าได้ใส่องค์ประกอบ <uses> ต่อไปนี้ หากไม่ได้ตั้งค่า ระบบจะใช้ตัวแฮนเดิลเริ่มต้นที่มีอยู่ใน Android Auto เพื่อจัดการข้อความ SMS/MMS ขาเข้าเมื่อตั้งค่าแอปของคุณเป็นแฮนเดิล SMS เริ่มต้น ซึ่งอาจทําให้เกิดการแจ้งเตือนซ้ำ

<automotiveApp>
    ...
    <uses name="sms" />
</automotiveApp>

นําเข้าไลบรารีหลักของ AndroidX

การสร้างการแจ้งเตือนเพื่อใช้กับอุปกรณ์ Auto ต้องใช้ไลบรารีหลัก AndroidX นําเข้าคลังลงในโปรเจ็กต์โดยทําดังนี้

  1. ในไฟล์ build.gradle ระดับบนสุด ให้ใส่การพึ่งพาที่เก็บ Maven ของ Google ดังที่แสดงในตัวอย่างต่อไปนี้

Groovy

allprojects {
    repositories {
        google()
    }
}

Kotlin

allprojects {
    repositories {
        google()
    }
}
  1. ในไฟล์ build.gradle ของโมดูลแอป ให้ใส่ทรัพยากร Dependency ของไลบรารี AndroidX Core ดังที่แสดงในตัวอย่างต่อไปนี้

Groovy

dependencies {
    // If your app is written in Java
    implementation 'androidx.core:core:1.15.0'

    // If your app is written in Kotlin
    implementation 'androidx.core:core-ktx:1.15.0'
}

Kotlin

dependencies {
    // If your app is written in Java
    implementation("androidx.core:core:1.15.0")

    // If your app is written in Kotlin
    implementation("androidx.core:core-ktx:1.15.0")
}

จัดการการดำเนินการของผู้ใช้

แอปรับส่งข้อความต้องมีวิธีจัดการการอัปเดตการสนทนาผ่าน Action สำหรับ Android Auto Action ออบเจ็กต์ 2 ประเภทที่แอปของคุณต้องจัดการ ได้แก่ การตอบกลับและการทําเครื่องหมายว่าอ่านแล้ว เราขอแนะนำให้จัดการโดยใช้ IntentService ซึ่งให้ความยืดหยุ่นในการจัดการการเรียกใช้ที่อาจใช้ทรัพยากรมากในเบื้องหลัง ซึ่งจะช่วยปลดภาระให้กับเธรดหลักของแอป

กําหนดการดําเนินการผ่าน Intent

การดำเนินการ Intent คือสตริงง่ายๆ ที่ระบุวัตถุประสงค์ของ Intent เนื่องจากบริการเดียวสามารถจัดการ Intent หลายประเภทได้ คุณจึงกำหนดสตริงการดำเนินการหลายรายการได้ง่ายกว่าการกำหนดคอมโพเนนต์ IntentService หลายรายการ

แอปรับส่งข้อความตัวอย่างของคู่มือนี้มีการดำเนินการ 2 ประเภทที่จำเป็น ได้แก่ การตอบกลับและการทําเครื่องหมายว่าอ่านแล้ว ดังที่แสดงในตัวอย่างโค้ดต่อไปนี้

private const val ACTION_REPLY = "com.example.REPLY"
private const val ACTION_MARK_AS_READ = "com.example.MARK_AS_READ"

สร้างบริการ

หากต้องการสร้างบริการที่จัดการออบเจ็กต์ Action เหล่านี้ คุณต้องมีรหัสการสนทนา ซึ่งเป็นโครงสร้างข้อมูลที่แอปของคุณกำหนดขึ้นเพื่อระบุการสนทนา คุณต้องมีกุญแจอินพุตระยะไกลด้วย ซึ่งจะอธิบายอย่างละเอียดในส่วนนี้ในภายหลัง ตัวอย่างโค้ดต่อไปนี้สร้างบริการเพื่อจัดการการดำเนินการที่จําเป็น

private const val EXTRA_CONVERSATION_ID_KEY = "conversation_id"
private const val REMOTE_INPUT_RESULT_KEY = "reply_input"

/**
 * An [IntentService] that handles reply and mark-as-read actions for
 * [YourAppConversation]s.
 */
class MessagingService : IntentService("MessagingService") {
    override fun onHandleIntent(intent: Intent?) {
        // Fetches internal data.
        val conversationId = intent!!.getIntExtra(EXTRA_CONVERSATION_ID_KEY, -1)

        // Searches the database for that conversation.
        val conversation = YourAppConversation.getById(conversationId)

        // Handles the action that was requested in the intent. The TODOs
        // are addressed in a later section.
        when (intent.action) {
            ACTION_REPLY -> TODO()
            ACTION_MARK_AS_READ -> TODO()
        }
    }
}

หากต้องการเชื่อมโยงบริการนี้กับแอป คุณจะต้องลงทะเบียนบริการในไฟล์ Manifest ของแอปด้วย ดังที่แสดงในตัวอย่างต่อไปนี้

<application>
    <service android:name="com.example.MessagingService" />
    ...
</application>

สร้างและจัดการ Intent

แอปอื่นๆ รวมถึง Android Auto ไม่สามารถรับ Intent ที่ทริกเกอร์ MessagingService ได้ เนื่องจากระบบจะส่ง Intent ไปยังแอปอื่นๆ ผ่าน PendingIntent ด้วยเหตุนี้ คุณจึงต้องสร้างออบเจ็กต์ RemoteInput เพื่อให้แอปอื่นๆ ส่งข้อความตอบกลับไปยังแอปของคุณได้ ดังที่แสดงในตัวอย่างต่อไปนี้

/**
 * Creates a [RemoteInput] that lets remote apps provide a response string
 * to the underlying [Intent] within a [PendingIntent].
 */
fun createReplyRemoteInput(context: Context): RemoteInput {
    // RemoteInput.Builder accepts a single parameter: the key to use to store
    // the response in.
    return RemoteInput.Builder(REMOTE_INPUT_RESULT_KEY).build()
    // Note that the RemoteInput has no knowledge of the conversation. This is
    // because the data for the RemoteInput is bound to the reply Intent using
    // static methods in the RemoteInput class.
}

/** Creates an [Intent] that handles replying to the given [appConversation]. */
fun createReplyIntent(
        context: Context, appConversation: YourAppConversation): Intent {
    // Creates the intent backed by the MessagingService.
    val intent = Intent(context, MessagingService::class.java)

    // Lets the MessagingService know this is a reply request.
    intent.action = ACTION_REPLY

    // Provides the ID of the conversation that the reply applies to.
    intent.putExtra(EXTRA_CONVERSATION_ID_KEY, appConversation.id)

    return intent
}

ในประโยคเงื่อนไข ACTION_REPLY ภายใน MessagingService ให้ดึงข้อมูลที่จะไปอยู่ในคําตอบ Intent ดังที่แสดงในตัวอย่างต่อไปนี้

ACTION_REPLY -> {
    // Extracts reply response from the intent using the same key that the
    // RemoteInput uses.
    val results: Bundle = RemoteInput.getResultsFromIntent(intent)
    val message = results.getString(REMOTE_INPUT_RESULT_KEY)

    // This conversation object comes from the MessagingService.
    conversation.reply(message)
}

คุณจัดการการทําเครื่องหมายว่าอ่านแล้ว Intent ในลักษณะที่คล้ายกัน แต่ไม่จำเป็นต้องมี RemoteInput ดังที่แสดงในตัวอย่างต่อไปนี้

/** Creates an [Intent] that handles marking the [appConversation] as read. */
fun createMarkAsReadIntent(
        context: Context, appConversation: YourAppConversation): Intent {
    val intent = Intent(context, MessagingService::class.java)
    intent.action = ACTION_MARK_AS_READ
    intent.putExtra(EXTRA_CONVERSATION_ID_KEY, appConversation.id)
    return intent
}

ACTION_MARK_AS_READ ประโยค Switch ภายใน MessagingService ไม่จําเป็นต้องใช้ตรรกะเพิ่มเติม ดังที่แสดงในตัวอย่างต่อไปนี้

// Marking as read has no other logic.
ACTION_MARK_AS_READ -> conversation.markAsRead()

แจ้งผู้ใช้เกี่ยวกับข้อความ

เมื่อจัดการการดำเนินการจากการสนทนาเสร็จแล้ว ขั้นตอนถัดไปคือการสร้างการแจ้งเตือนที่เป็นไปตามข้อกำหนดของ Android Auto

สร้างการดำเนินการ

คุณสามารถส่งออบเจ็กต์ Action ไปยังแอปอื่นๆ โดยใช้ Notification เพื่อเรียกใช้เมธอดในแอปเดิม วิธีนี้ช่วยให้ Android Auto ทำเครื่องหมายการสนทนาว่าอ่านแล้วหรือตอบกลับได้

หากต้องการสร้าง Action ให้เริ่มต้นด้วย Intent ตัวอย่างต่อไปนี้แสดงวิธีสร้าง "คำตอบ" Intent

fun createReplyAction(
        context: Context, appConversation: YourAppConversation): Action {
    val replyIntent: Intent = createReplyIntent(context, appConversation)
    // ...

จากนั้นรวม Intent นี้ไว้ใน PendingIntent ซึ่งเตรียมไว้สําหรับการใช้งานแอปภายนอก PendingIntent จะล็อกการเข้าถึงทั้งหมดไปยัง Intent ที่รวมไว้โดยแสดงเฉพาะชุดเมธอดที่เลือกซึ่งช่วยให้แอปฝั่งที่รับเรียกใช้ Intent หรือรับชื่อแพ็กเกจของแอปต้นทางได้ แอปภายนอกจะไม่สามารถเข้าถึง Intent หรือข้อมูลภายในได้

    // ...
    val replyPendingIntent = PendingIntent.getService(
        context,
        createReplyId(appConversation), // Method explained later.
        replyIntent,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
    // ...

ก่อนตั้งค่าการตอบกลับ Action โปรดทราบว่า Android Auto มีข้อกำหนด 3 ข้อสำหรับการตอบกลับ Action ดังนี้

  • ต้องตั้งค่าการดำเนินการตามความหมายเป็น Action.SEMANTIC_ACTION_REPLY
  • Action ต้องระบุว่าจะไม่แสดงอินเทอร์เฟซผู้ใช้เมื่อเรียกใช้
  • Action ต้องมี RemoteInput รายการเดียว

ตัวอย่างโค้ดต่อไปนี้จะตั้งค่าการตอบกลับ Action ที่เป็นไปตามข้อกำหนดที่ระบุไว้ข้างต้น

    // ...
    val replyAction = Action.Builder(R.drawable.reply, "Reply", replyPendingIntent)
        // Provides context to what firing the Action does.
        .setSemanticAction(Action.SEMANTIC_ACTION_REPLY)

        // The action doesn't show any UI, as required by Android Auto.
        .setShowsUserInterface(false)

        // Don't forget the reply RemoteInput. Android Auto will use this to
        // make a system call that will add the response string into
        // the reply intent so it can be extracted by the messaging app.
        .addRemoteInput(createReplyRemoteInput(context))
        .build()

    return replyAction
}

การจัดการการดำเนินการ "ทำเครื่องหมายว่าอ่านแล้ว" จะคล้ายกัน ยกเว้นจะไม่มี RemoteInput ดังนั้น Android Auto จึงมีข้อกำหนด 2 ข้อสำหรับ Action การทำเครื่องหมายว่าอ่านแล้ว

  • การกระทำตามความหมายตั้งค่าเป็น Action.SEMANTIC_ACTION_MARK_AS_READ
  • การดําเนินการบ่งชี้ว่าจะไม่แสดงอินเทอร์เฟซผู้ใช้เมื่อเริ่มทํางาน

ตัวอย่างโค้ดต่อไปนี้จะตั้งค่าการทําเครื่องหมายว่าอ่านแล้ว Action ที่เป็นไปตามข้อกําหนดเหล่านี้

fun createMarkAsReadAction(
        context: Context, appConversation: YourAppConversation): Action {
    val markAsReadIntent = createMarkAsReadIntent(context, appConversation)
    val markAsReadPendingIntent = PendingIntent.getService(
            context,
            createMarkAsReadId(appConversation), // Method explained below.
            markAsReadIntent,
            PendingIntent.FLAG_UPDATE_CURRENT  or PendingIntent.FLAG_IMMUTABLE)
    val markAsReadAction = Action.Builder(
            R.drawable.mark_as_read, "Mark as Read", markAsReadPendingIntent)
        .setSemanticAction(Action.SEMANTIC_ACTION_MARK_AS_READ)
        .setShowsUserInterface(false)
        .build()
    return markAsReadAction
}

เมื่อสร้าง Intent ที่รอดำเนินการ ระบบจะใช้ 2 วิธี ได้แก่ createReplyId() และ createMarkAsReadId() วิธีการเหล่านี้ทำหน้าที่เป็นรหัสคำขอสำหรับ PendingIntent แต่ละรายการ ซึ่ง Android จะใช้เพื่อควบคุม Intent ที่รอดำเนินการที่มีอยู่ เมธอด create() ต้องแสดงผลรหัสที่ไม่ซ้ำกันสำหรับการสนทนาแต่ละครั้ง แต่การเรียกใช้ซ้ำสำหรับการสนทนาเดียวกันต้องแสดงผลรหัสที่ไม่ซ้ำกันซึ่งสร้างขึ้นแล้ว

ลองดูตัวอย่างการสนทนา 2 รายการ ได้แก่ ก. และ ข. รหัสการตอบกลับของการสนทนา ก. คือ 100 และรหัสการทําเครื่องหมายว่าอ่านแล้วคือ 101 รหัสการตอบกลับของการสนทนา ข. คือ 102 และรหัสการทําเครื่องหมายว่าอ่านแล้วคือ 103 หากการสนทนา ก. ได้รับการอัปเดต รหัสการตอบกลับและรหัสทําเครื่องหมายว่าอ่านแล้วจะยังคงเป็น 100 และ 101 ดูข้อมูลเพิ่มเติมได้ที่ PendingIntent.FLAG_UPDATE_CURRENT

สร้าง MessagingStyle

MessagingStyle เป็นผู้ให้บริการข้อมูลการรับส่งข้อความ และเป็นวิธีที่ Android Auto ใช้อ่านออกเสียงข้อความแต่ละรายการในการสนทนา

ก่อนอื่น คุณต้องระบุผู้ใช้อุปกรณ์ในรูปแบบออบเจ็กต์ Person ดังที่แสดงในตัวอย่างต่อไปนี้

fun createMessagingStyle(
        context: Context, appConversation: YourAppConversation): MessagingStyle {
    // Method defined by the messaging app.
    val appDeviceUser: YourAppUser = getAppDeviceUser()

    val devicePerson = Person.Builder()
        // The display name (also the name that's read aloud in Android auto).
        .setName(appDeviceUser.name)

        // The icon to show in the notification shade in the system UI (outside
        // of Android Auto).
        .setIcon(appDeviceUser.icon)

        // A unique key in case there are multiple people in this conversation with
        // the same name.
        .setKey(appDeviceUser.id)
        .build()
    // ...

จากนั้นคุณสามารถสร้างออบเจ็กต์ MessagingStyle และระบุรายละเอียดบางอย่างเกี่ยวกับการสนทนา

    // ...
    val messagingStyle = MessagingStyle(devicePerson)

    // Sets the conversation title. If the app's target version is lower
    // than P, this will automatically mark the conversation as a group (to
    // maintain backward compatibility). Use `setGroupConversation` after
    // setting the conversation title to explicitly override this behavior. See
    // the documentation for more information.
    messagingStyle.setConversationTitle(appConversation.title)

    // Group conversation means there is more than 1 recipient, so set it as such.
    messagingStyle.setGroupConversation(appConversation.recipients.size > 1)
    // ...

สุดท้าย ให้เพิ่มข้อความที่ยังไม่ได้อ่าน

    // ...
    for (appMessage in appConversation.getUnreadMessages()) {
        // The sender is also represented using a Person object.
        val senderPerson = Person.Builder()
            .setName(appMessage.sender.name)
            .setIcon(appMessage.sender.icon)
            .setKey(appMessage.sender.id)
            .build()

        // Adds the message. More complex messages, like images,
        // can be created and added by instantiating the MessagingStyle.Message
        // class directly. See documentation for details.
        messagingStyle.addMessage(
                appMessage.body, appMessage.timeReceived, senderPerson)
    }

    return messagingStyle
}

แพ็กเกจและส่งการแจ้งเตือน

หลังจากสร้างออบเจ็กต์ Action และ MessagingStyle แล้ว คุณจะสร้างและโพสต์ Notification ได้

fun notify(context: Context, appConversation: YourAppConversation) {
    // Creates the actions and MessagingStyle.
    val replyAction = createReplyAction(context, appConversation)
    val markAsReadAction = createMarkAsReadAction(context, appConversation)
    val messagingStyle = createMessagingStyle(context, appConversation)

    // Creates the notification.
    val notification = NotificationCompat.Builder(context, channel)
        // A required field for the Android UI.
        .setSmallIcon(R.drawable.notification_icon)

        // Shows in Android Auto as the conversation image.
        .setLargeIcon(appConversation.icon)

        // Adds MessagingStyle.
        .setStyle(messagingStyle)

        // Adds reply action.
        .addAction(replyAction)

        // Makes the mark-as-read action invisible, so it doesn't appear
        // in the Android UI but the app satisfies Android Auto's
        // mark-as-read Action requirement. Both required actions can be made
        // visible or invisible; it is a stylistic choice.
        .addInvisibleAction(markAsReadAction)

        .build()

    // Posts the notification for the user to see.
    val notificationManagerCompat = NotificationManagerCompat.from(context)
    notificationManagerCompat.notify(appConversation.id, notification)
}

แหล่งข้อมูลเพิ่มเติม

รายงานปัญหาการรับส่งข้อความของ Android Auto

หากพบปัญหาขณะพัฒนาแอปรับส่งข้อความสำหรับ Android Auto คุณสามารถรายงานปัญหาได้โดยใช้เครื่องมือติดตามปัญหาของ Google โปรดกรอกข้อมูลที่ขอทั้งหมดในเทมเพลตปัญหา

สร้างปัญหาใหม่

ก่อนรายงานปัญหาใหม่ โปรดตรวจสอบว่าปัญหาดังกล่าวได้รับการรายงานแล้วในรายการปัญหาหรือไม่ คุณสามารถติดตามและโหวตปัญหาได้โดยคลิกดาวสำหรับปัญหาในเครื่องมือติดตาม ดูข้อมูลเพิ่มเติมได้ที่การติดตามปัญหา