ขยายการแจ้งเตือนการรับส่งข้อความไปยัง Android Auto

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

คู่มือนี้แสดงวิธีขยายแอปที่แสดงข้อความต่อผู้ใช้และรับคำตอบของผู้ใช้ เช่น แอปแชท เพื่อส่งต่อการแสดงข้อความและการรับคำตอบไปยังอุปกรณ์อัตโนมัติ การผสานรวมนี้จะช่วยให้ผู้ใช้ดูได้เฉพาะประวัติข้อความจากการแจ้งเตือนที่ได้รับในระหว่างเซสชัน Android Auto ที่ใช้งานอยู่ เท่านั้น หากต้องการแสดงข้อความจากก่อนที่เซสชัน Android 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 รายการ และเพื่อให้เป็นไปตามข้อกำหนดของ Android Auto แอป ต้องแนบออบเจ็กต์การตอบกลับและออบเจ็กต์ทำเครื่องหมายว่าอ่านแล้ว Action ไปยัง Notification

โฟลว์การรับส่งข้อความ

ส่วนนี้อธิบายโฟลว์การรับส่งข้อความทั่วไประหว่างแอปของคุณกับ 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.17.0'

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

Kotlin

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

    // If your app is written in Kotlin
    implementation("androidx.core:core-ktx:1.17.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>

สร้างและจัดการความตั้งใจ

แอปอื่นๆ รวมถึง 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 switch clause ภายใน 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 สวิตช์คลอสภายใน 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
}

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

ลองพิจารณาตัวอย่างที่มีการสนทนา 2 รายการ ได้แก่ A และ B โดยการสนทนา A มีรหัสการตอบกลับเป็น 100 และรหัสการทำเครื่องหมายว่าอ่านแล้วเป็น 101 รหัสการตอบกลับของ Conversation B คือ 102 และรหัสการทำเครื่องหมายว่าอ่านแล้วคือ 103 หากมีการอัปเดตการสนทนา A รหัสการตอบกลับและรหัสว่าอ่านแล้วจะยังคงเป็น 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 โปรดกรอกข้อมูลที่ขอทั้งหมดในเทมเพลตปัญหา

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

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