Messaging-Apps für Android Auto entwickeln

Die Kategorie „Kommunikation“ ist bald verfügbar
Die Kategorie „Nachrichten“ wird erweitert, um neue Funktionen wie den Nachrichtenverlauf und Anruffunktionen hinzuzufügen

Für viele Fahrer ist es wichtig, über Nachrichten in Verbindung zu bleiben. Mit Chat-Apps können Nutzer ob ein Kind abgeholt werden muss oder der Ort für das Abendessen geändert wurde. Mit dem Android-Framework können Messaging-Apps ihre Fahrdienste über eine Standard-Benutzeroberfläche, über die Fahrer auf die Straße blicken.

Apps, die die Nachrichtenfunktion unterstützen, können ihre Messaging-Benachrichtigungen auf Android Auto erweitern und sie verbrauchen, wenn Auto ausgeführt wird. Diese Benachrichtigungen werden in „Automatisch“ angezeigt und Nachrichten auf einer einheitlichen, wenig abgelenkten Oberfläche lesen und beantworten. Und wenn Sie die MessagingStyle API erhalten Sie optimierte Benachrichtigungen für alle Android-Geräte, einschließlich Android Auto. Zu den Optimierungen gehört eine Benutzeroberfläche, die auf Benachrichtigungen über Nachrichten, verbesserte Animationen und Unterstützung für Inline-Bilder.

In diesem Leitfaden erfahren Sie, wie Sie eine App, die dem Nutzer Nachrichten anzeigt, die Antworten des Nutzers, z. B. in einer Chat-App, Empfangsbestätigung an ein Android Auto-Gerät senden. Eine entsprechende Anleitung zum Design finden Sie unter Messaging". Apps Design for Driving.

Erste Schritte

Um den Nachrichtendienst für Android Auto-Geräte bereitzustellen, muss deine App ihre Unterstützung für Android Auto in der Manifest-Datei angegeben und können Folgendes tun:

  • Erstellen und senden NotificationCompat.MessagingStyle -Objekte, die „Antworten“- und „Als gelesen markieren“-Action-Objekte enthalten.
  • Das Beantworten und Markieren einer Konversation mit einem Service als gelesen verarbeiten.

Konzepte und Objekte

Bevor Sie mit dem Design Ihrer App beginnen, sollten Sie wissen, wie Android Auto die Kommunikation übernimmt.

Ein einzelner Kommunikationsblock wird als Nachricht bezeichnet und durch die Klasse MessagingStyle.Message. Eine Nachricht enthält einen Absender, und den Zeitpunkt, zu dem die Nachricht gesendet wurde.

Die Kommunikation zwischen Nutzern wird als Unterhaltung bezeichnet und durch MessagingStyle-Objekt. Eine Konversation oder MessagingStyle enthält einen Titel, und ob die Unterhaltung in einer Gruppe von Nutzern stattfindet.

Um Nutzer über Updates für eine Unterhaltung zu informieren, z. B. eine neue Nachricht, werden in Apps gepostete Nachrichten Notification mit dem Android-System verbinden. Dieses Notification verwendet das MessagingStyle-Objekt, um nachrichtenspezifische Nachrichten anzuzeigen Benutzeroberfläche in der Benachrichtigungsleiste Die Android-Plattform übergibt auch diese Notification in Android Auto hochgeladen. MessagingStyle wird extrahiert und verwendet, Benachrichtigung über das Autodisplay.

Außerdem müssen Apps für Android Auto Action-Objekte zu einem Notification hinzufügen, können Nutzer direkt auf eine Nachricht antworten oder sie als gelesen markieren Benachrichtigungsleiste.

Zusammenfassend lässt sich sagen, dass eine einzelne Unterhaltung durch ein Notification dargestellt wird. -Objekt, das mit einem MessagingStyle-Objekt formatiert wird. Das MessagingStyle enthält alle Nachrichten in dieser Konversation in einer oder mehreren MessagingStyle.Message-Objekte. Um die Anforderungen für Android Auto zu erfüllen, Action-Objekte zum Antworten und Markieren als gelesen an Notification anhängen.

Messaging-Ablauf

In diesem Abschnitt wird der typische Nachrichtenfluss zwischen Ihrer App und Android Auto beschrieben.

  1. Ihre App erhält eine Nachricht.
  2. Deine App generiert eine MessagingStyle-Benachrichtigung mit Antwort und Action-Objekte als gelesen markieren.
  3. Android Auto empfängt das Ereignis „Neue Benachrichtigung“ vom Android-System MessagingStyle, die Antwort Action und die Markierung als gelesen Action gefunden.
  4. Android Auto generiert eine Benachrichtigung und zeigt sie im Auto an.
  5. Wenn der Nutzer auf dem Display des Autos auf die Benachrichtigung tippt, löst das Action-Zeichen aus.
    • Ihre App muss dieses Markieren als gelesene Ereignisse im Hintergrund verarbeiten.
  6. Wenn der Nutzer per Sprachbefehl auf die Benachrichtigung reagiert, ein Transkript der Antwort des Nutzers in die Antwort Action und dann löst sie aus.
    • Dieses Antwortereignis muss von Ihrer App im Hintergrund verarbeitet werden.

Vorläufige Annahmen

Diese Seite enthält keine Anleitung zum Erstellen einer vollständigen Messaging-App. Die Das folgende Codebeispiel enthält einige der Dinge, die für Ihre App erforderlich sind. bevor Sie die Nachrichtenfunktion mit Android Auto unterstützen:

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-Unterstützung deklarieren

Wenn Android Auto eine Benachrichtigung von einer Messaging-App erhält, wird überprüft, Die App hat erklärt, dass sie Android Auto unterstützt. Um diese Unterstützung zu ermöglichen, fügen Sie den folgenden Eintrag im Manifest deiner App:

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

Dieser Manifesteintrag verweist auf eine andere XML-Datei, die du mit dem folgenden Pfad: YourAppProject/app/src/main/res/xml/automotive_app_desc.xml. Deklariere in automotive_app_desc.xml die Android Auto-Funktionen, die deine App nutzen kann unterstützt. Um beispielsweise die Unterstützung von Benachrichtigungen zu erklären, fügen Sie den Parameter Folgendes:

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

Wenn Ihre App als Standard-SMS-Handler festgelegt werden kann: Achte darauf, das folgende <uses>-Element anzugeben. Andernfalls wird eine Standardeinstellung In Android Auto integrierter Handler wird zur Verarbeitung eingehender SMS/MMS verwendet wenn deine App als Standard-SMS-Handler festgelegt ist, was zu doppelten Benachrichtigungen.

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

AndroidX-Kernbibliothek importieren

Zum Erstellen von Benachrichtigungen zur Verwendung mit Android Auto-Geräten ist die AndroidX-Kernbibliothek. Importieren Sie die Bibliothek in Ihr wie folgt erstellen:

  1. Füge in die Datei build.gradle auf oberster Ebene eine Abhängigkeit vom Maven von Google ein. Repository enthalten, wie im folgenden Beispiel gezeigt:

Cool

allprojects {
    repositories {
        google()
    }
}

Kotlin

allprojects {
    repositories {
        google()
    }
}
  1. Füge in die Datei build.gradle deines App-Moduls AndroidX Core ein. Bibliotheksabhängigkeit, wie im folgenden Beispiel gezeigt:

Cool

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

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

Kotlin

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

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

Nutzeraktionen verarbeiten

Ihre Messaging-App muss die Aktualisierung einer Konversation über ein Action Für Android Auto gibt es zwei Arten von Action-Objekten, die in deiner App verwendet werden die Aufgaben erfüllen muss: „Antworten“ und „Als gelesen markieren“. Wir empfehlen, ein IntentService, das bietet die Flexibilität, potenziell teure im Hintergrund aufgerufen, wodurch der Hauptthread Ihrer App freigegeben wird.

Intent-Aktionen definieren

Intent-Aktionen sind einfache Strings, die den Zweck der Intent angeben. Da ein einzelner Dienst mehrere Arten von Intents verarbeiten kann, Mehrere Aktionszeichenfolgen zu definieren, anstatt mehrere IntentService-Komponenten.

Die Beispiel-Messaging-App dieses Leitfadens enthält die beiden erforderlichen Aktionstypen: antworten und als gelesen markieren, wie im folgenden Codebeispiel gezeigt.

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

Dienst erstellen

Sie benötigen die Unterhaltungs-ID, um einen Dienst zu erstellen, der diese Action-Objekte verarbeitet. Hierbei handelt es sich um eine beliebige, von Ihrer App definierte Datenstruktur, die das Gespräch zu führen. Sie benötigen auch einen Remote-Eingabeschlüssel, der im weiter unten in diesem Abschnitt. Im folgenden Codebeispiel wird ein Dienst erstellt, die erforderlichen Aktionen auszuführen:

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()
        }
    }
}

Um diesen Dienst mit deiner App zu verknüpfen, musst du den Dienst auch registrieren im Manifest Ihrer App aus, wie im folgenden Beispiel gezeigt:

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

Intents generieren und verarbeiten

Andere Apps wie Android Auto können die Intent nicht erhalten , der die MessagingService auslöst, weil Intents an andere Apps übergeben werden über PendingIntent. Aus müssen Sie ein RemoteInput-Element -Objekt, damit andere Apps den Antworttext an Ihre App zurückgeben können (siehe Abbildung). im folgenden Beispiel:

/**
 * 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
}

In der ACTION_REPLY-Umschaltklausel innerhalb von MessagingService extrahieren Sie die Informationen, die in die Antwort Intent einfließen, wie im folgendes Beispiel:

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)
}

Die Intent-Funktion „Als gelesen markieren“ wird auf ähnliche Weise verarbeitet. Es funktioniert jedoch nicht, erfordern RemoteInput, wie im folgenden Beispiel gezeigt:

/** 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
}

Die ACTION_MARK_AS_READ-Umschaltklausel innerhalb von MessagingService erfordert keine weitere Logik, wie im folgenden Beispiel gezeigt:

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

Nutzer über Nachrichten informieren

Sobald die Konversationsaktion abgeschlossen ist, besteht der nächste Schritt darin, Benachrichtigungen generieren, die mit Android Auto kompatibel sind.

Aktionen erstellen

Action-Objekte können mithilfe von Notification an andere Apps übergeben werden, Auslösermethoden in der ursprünglichen App. So kann Android Auto als gelesen oder beantworten.

Wenn du ein Action erstellen möchtest, beginne mit einem Intent. Im folgenden Beispiel sehen Sie, wie eine Antwort erstellt wird, Intent:

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

Verpacken Sie diese Intent dann in einem PendingIntent, um sie für den externen Gebrauch vorzubereiten. App-Nutzung. Ein PendingIntent sperrt den gesamten Zugriff auf das umschlossene Intent durch werden nur ausgewählte Methoden zur Verfügung gestellt, mit denen die empfangende App Intent oder rufen Sie den Paketnamen der ursprünglichen App ab. Externe App kann niemals auf das zugrunde liegende Intent oder die darin enthaltenen Daten zugreifen.

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

Bevor du die Antwort Action einrichtest, beachte, dass Android Auto drei Anforderungen an die Antwort Action:

  • Die semantische Aktion muss auf Action.SEMANTIC_ACTION_REPLY festgelegt werden.
  • Action muss angeben, dass beim Auslösen keine Benutzeroberfläche angezeigt wird.
  • Action muss einen einzelnen RemoteInput enthalten.

Mit dem folgenden Codebeispiel wird eine Antwort Action eingerichtet, die die die oben aufgeführten Anforderungen erfüllt:

    // ...
    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
}

Die Aktion „Als gelesen markieren“ wird ähnlich verarbeitet, außer dass es keine RemoteInput gibt. Für Android Auto gelten daher zwei Anforderungen für die Markierung als gelesen Action:

  • Die semantische Aktion ist auf Action.SEMANTIC_ACTION_MARK_AS_READ festgelegt.
  • Die Aktion gibt an, dass beim Auslösen keine Benutzeroberfläche angezeigt wird.

Im folgenden Codebeispiel wird eine Action-Markierung zum Lesen eingerichtet, die diese Anforderungen:

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
}

Beim Generieren der ausstehenden Intents werden zwei Methoden verwendet: createReplyId() und createMarkAsReadId(). Diese Methoden dienen als Anfragecodes für jede PendingIntent, die von Android zur Steuerung verwendet werden vorhandene ausstehende Intents. Die create()-Methoden müssen gibt eindeutige IDs für jede Konversation zurück, aber wiederholte Aufrufe für dieselbe Konversation muss die bereits generierte eindeutige ID zurückgeben.

Nehmen wir ein Beispiel mit zwei Konversationen, A und B: Die Antwort-ID von Konversation A lautet 100. und die Mark-as-Read-ID lautet 101. Die Antwort-ID von Konversation B lautet 102 und seine Mark-as-Read-ID ist 103. Wenn Konversation A aktualisiert wird, Die IDs „Antworten“ und „Als gelesen markieren“ sind immer noch 100 und 101. Weitere Informationen finden Sie unter PendingIntent.FLAG_UPDATE_CURRENT

Nachrichtenstil erstellen

MessagingStyle ist der Anbieter der Messaging-Informationen und das, was Android Automatisch verwendet, um jede Nachricht in einer Konversation vorzulesen.

Zuerst muss der Nutzer des Geräts in Form eines Person-Objekt, wie im folgendes Beispiel:

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()
    // ...

Anschließend können Sie das MessagingStyle-Objekt erstellen und einige Details angeben. über das Gespräch.

    // ...
    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)
    // ...

Fügen Sie zum Schluss die ungelesenen Nachrichten hinzu.

    // ...
    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
}

Verpacken und Benachrichtigung senden

Nach dem Generieren der Objekte Action und MessagingStyle können Sie Folgendes tun: Notification erstellen und hochladen.

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)
}

Weitere Informationen

Problem mit Android Auto Messaging melden

Wenn bei der Entwicklung Ihrer Messaging-App für Android Auto Probleme auftreten, können Sie dies mit der Problemverfolgung von Google Geben Sie alle erforderlichen Informationen in der Problemvorlage an.

Neues Problem erstellen

Bevor Sie ein neues Problem melden, prüfen Sie, ob es bereits in den Problemen gemeldet wurde Liste. Sie können Themen abonnieren und abstimmen, indem Sie auf den Stern für ein Problem in klicken: den Tracker. Weitere Informationen finden Sie unter Eine Ausgabe abonnieren: