Apps für Android programmieren leicht gemacht!
Nachricht von Handy an Smartwatch schicken

Nachricht von Handy an Smartwatch schicken

Nachdem wir ja bereits eine erste „Hello World!“ Smartwatch App erstellt, das Bluetooth Debugging aktiviert, die Google Wear API eingerichtet und einen API Schlüssel erhalten haben möchte ich in diesem Artikel unsere App etwas erweitern.

Wie bereits angesprochen stellt unsere Smartwatch lediglich eine Erweiterung unseres Smartphones da und ist im eigentlichen Sinne kein eigenständiges Gerät. Deshalb müssen wir lernen, wie unsere Smartwatch App mit unserer Smartphone App kommunizieren kann. Diese Kommunikation stellt gleichzeitig den einzigen Weg da, um in unserer Smartwatch App an Daten aus dem Internet zu gelangen. Weiter noch sollten wir versuchen keine größeren Datenmengen auf unserer Smartwatch zu speichern, sondern Datenbanken in der Smartphone App erstellen. Benötigen wir besondere Datensätze, so können wir diese ja vom Smartphone erhalten.

Bevor wir mit unserer App beginnen können Nachrichten zu versenden ist es wichtig, dass ihr alle oben erwähnten Artikel durchgearbeitet habt. Die Artikel dienen als Grundlage für die Kommunikation.

Ich werde diesen Artikel in zwei Teile teilen. Vorerst beschäftigen wir uns mit der Smartphone App. Im Nachhinein werden wir dann den Empfang der Nachrichten auf der Smartwatch betrachten.

 

Smartphone:

Vorarbeit:

Solltet ihr als Grundgerüst die bereits erstellte „Hello World!“ Smartwatch App nutzen, dann könnt ihr diesen Teil überspringen.
Solltet ihr eure bereits bestehende App erweitern wollen, dann öffnet die Datei „build.gradle (Module: mobile)“.
Schreibt in die {}-Klammer von „dependencies“:

wearApp project(':wear')
compile 'com.google.android.gms:play-services-wearable:9.0.2'

 

Wear API:

Bitte folgt hier der Anleitung in unserem Artikel Google Wear API.
Wenn ihr eure bereits bestehende App erweitert, dann könnt ihr den Teil mit der Smartwatch App vorerst überspringen (das werden wir später nachholen).
Nutzt ihr die „Hello World!“ Smartwatch App, dann führt diesen Teil bitte trotzdem durch.

 

Java Code:

Wir sollten alle nötigen Vorbereitungen getroffen haben.
Alle Imports sind getätigt und die Wear API steht. Machen wir uns nun daran, Nachrichten zu versenden. Im späteren Verlauf dieses Artikels werden wir lernen, wie wir Nachrichten dann auch auf der Smartwatch empfangen.

Aber ACHTUNG: Es handelt sich um Fire-And-Forget Anfragen. Dies bedeutet, dass unsere Smartphone App die Nachrichten nur sendet. Ob die Nachrichten nun auch empfangen werden wird nicht geprüft. Ergo kann es passieren, dass wir eine Nachricht senden, diese aber nie empfangen wird. Darauf können wir nicht prüfen.

Wir müssen unserer Nachricht zunächst einen Pfad geben. Dieser Pfad wird mit der Nachricht selber übergeben und kann in der Smartwatch App dann genutzt werden, um herauszufinden für was die Nachricht gedacht ist. Wir könnten somit mehrere Events definieren, die selbe Nachricht übergeben und trotzdem verschiedene Dinge auslösen.

Ein Beispiel:
Wir haben mehrere Textfelder auf der Uhr. Senden wir nun die Nachricht „Test“ und den Pfad „titel_feld“, dann wird auf der Uhr der Text „Test“ in das Titeltextfeld geschrieben.
Senden wir jedoch die Nachricht „Test“ und den Pfad „text_feld“, dann wird „Test“ in das Texttextfeld geschrieben.

Ich definiere in diesem Artikel mal nur einen Pfad und gebe ihn als globale finale Variable an.

private static final String WEAR_MESSAGE_PATH = "/nachricht";

Um eine Nachricht zu senden können wir eine Funktion nutzen, wie diese:

private void sendeNachricht( final String path, final String text ) {
    new Thread( new Runnable() {
        @Override
        public void run() {
            NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes( mApiClient ).await();
            for(Node node : nodes.getNodes()) {

                // Hier wird die Nachricht an alle mit dem Handy verbundenen Wear Geräte gesendet.
                MessageApi.SendMessageResult result = Wearable.MessageApi.sendMessage(
                        mApiClient, node.getId(), path, text.getBytes() ).await();
            }

            runOnUiThread( new Runnable() {
                @Override
                public void run() {
                    // Hier kann man etwas mit dem Aussehen der App verändern.
                    // Bitte keine großen Berechnungen durchführen, da dies hier die App zum einfrieren bringen kann.
                }
            });
        }
    }).start();
}

 

Einschränkungen:

Wir dürfen Nachrichten allerdings erst senden, wenn unsere Wear Api eine Verbindung aufgebaut hat.
Ergo sollten wir noch eine Variable nutzen, um in der Funktion „sendeNachricht“ zu prüfen, ob bereits eine Verbindung besteht.

private void sendeNachricht( final String path, final String text ) {
    if(mApiClient.isConnected()) {
              
        [...]
            
    }else{
        // Hier könnten wir eine Fehlermeldung ausgeben, weil noch keine Verbindung besteht.
    }
}

Fügt an der Stelle „[…]“ einfach die Zeilen 2-21 des vorigen Codes ein und ihr seit auf der sicheren Seite.

 

 

Smartwatch:

Neue Smartwatch App erstellen:

Solltet ihr die „Hello World!“ Smartwatch App nutzen, dann überspring diesen Teil.
Wollen wir jedoch zu einer bestehenden Smartphone App eine neue Smartwatch App hinzufügen, dann können wir das wie folgt erledigen:

  • Obere Leiste -> File -> New -> New Module
  • Android Wear Module
  • Namen vergeben und min. SDK angeben
  • Blank Wear Activity
  • Finish

 

Wear API:

Wir müssen nun die Google Wear Api auch in der Smartwatch App hinzufügen.
Bitte folgt hier der Anleitung in unserem Artikel Google Wear API.
Wichtig sind hier die Abschnitte „android_manifest.xml“, „Google Play Service API importieren“ und „Smartwatch App“.

 

Android_Manifest.xml:

Zusätzlich zu den bereits erfolgten Änderungen an der Android_Manifest.xml Datei müssen wir nun in der Wear App zusätzlich noch einen Service registrieren, der auf die Nachrichten reagiert. Dieser Listener ist eine eigenständige Klasse und startet im Fall der Fälle eine Funktion in unserer Hauptapp, in der wir dann die Nachrichten verarbeiten können.

Schaubild, zur Kommunikation zwischen Smartwatch und Smartphone.
Schaubild, zur Kommunikation zwischen Smartwatch und Smartphone.
<manifest ... >

    [...]

    <application ... >

        [...]

        <service android:name=".WearMessageListenerService">
            <intent-filter>
                <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
            </intent-filter>
        </service>

    </application>

</manifest>

 

 

Java Code:

Es gilt die Nachrichten auch zu empfangen, sonst wäre unsere gesendete Nachricht ja witzlos.
Es bedarf nun eines Listeners.
Wir erstellen eine neue Klasse „WearMessageListenerService“ und schreiben:

public class WearMessageListenerService extends WearableListenerService {

    @Override
    public void onMessageReceived(MessageEvent messageEvent) {
        
            super.onMessageReceived(messageEvent);
        
    }

}

Die Zeile „super.onMessageReceived(messageEvent);“ bewirkt, dass die Standardfunktion „onMessageReceived“ gestartet wird, wenn eine Nachricht empfangen wurde.

 

Um nun unsere eigene Logik zu programmieren sollten wir die Funktion etwas umschreiben.
Die Funktion „onMessageReceived“ sieht nun so oder so ähnlich aus:

@Override
public void onMessageReceived( final MessageEvent messageEvent ) {
    runOnUiThread( new Runnable() {
        @Override
        public void run() {
            if( messageEvent.getPath().equalsIgnoreCase( WEAR_MESSAGE_PATH ) ) {
                String nachricht = messageEvent.getData();;
            }
        }
    });
}

Nachdem wir den String „nachricht“ in der 7. Zeile erhalten haben könnten wir beispielsweise eine weitere Funktion aufrufen und etwas mit der erhaltenen Nachricht anfangen.

 

Schlussendlich erstellen wir auch hier wieder eine unveränderliche globale Variable, welche unseren Pfad enthält.

private static final String WEAR_MESSAGE_PATH = "/nachricht";

Marvin

Ich bin 23 Jahre jung und studiere zurzeit Wirtschaftsinformatik an der Georg-August-Universität in Göttingen. Ich bin ein Mensch, der sich neben der Programmierung noch für tausend andere Dinge interessiert, die mal mehr und mal weniger verrückt sind. Vor allem aber bin ich Feuer und Flamme mit der Programmierung von eigenen kleinen Apps und Programmen, die mein Leben bereichern.

8 Kommentare

*Pflichtfeld

  • Hey,

    Ich versuche gerade meine erste Smartwatch-App zu programmieren und frage mich in welcher Klasse sich nachher der Code zum Senden der Nachricht befinden muss.
    Falls das irgendwo steht hab ich es überlesen.

    • Hallo Nina,
      die Funktionen zum Senden der Nachricht an die Smartwatch kann in jeder beliebigen Klasse stehen.
      Am besten verpackst du die Funktionen in die Klasse, aus der du die Nachricht senden möchtest.

      Der Code zum Empfangen der Nachrichten auf der Smartwatch muss in die Klasse, die in der AndroidManifest.xml Datei definiert ist. In diesem Artikel lautet diese „WearMessageListenerService“.

      Gruß,
      Marvin

  • Hey,

    kannst du mir auch sagen, wo die unveränderlichen globalen Variablen hinkommen? Ich bin nämlich irgendwie verwirrt, da ich nicht glaube, dass die mit allem anderen in eine Klasse kommen, oder?

    VG,
    Nina

    • Hallo Nina,

      globale Variablen gehören immer in die Klasse, in der sie zur Verwendung kommen, aber nicht in eine der Funktionen.
      Dadurch sind sie in jeder der Funktionen verfügbar.

      Heißt deine Klasse also Beispielsweise „MainActivity“, dann schreibst du:
      public class MainActivity{

      [Hier gehören die globalen Variablen hin]

      public void eineFunktion(){
      [...]
      }

      }

      Mehr dazu findest du in diesem Artikel: Lebensdauer von Variablen
      Schau dir dort mal den Abschnitt „Lebensdauer von Variablen“ und die Variable „i“ an. Diese ist global definiert.

      Gruß,
      Marvin

    • Hallo Lina,
      die Funktion onMessageReceived wird von Android bzw. Android Wear aufgerufen, wenn eine Nachricht empfangen wurde.
      Wir selber initialisieren den Aufruf, indem wir eine Nachricht an die Smartwatch senden.

      Gruß,
      Marvin

  • Hey 🙂
    und was mach ich dann mit der Variable „result“ in der Funktion „sendeNachricht“? Bei mir wird nämlich angezeigt „Variable result is never used“.

    Liebe Grüße

    Lina

    • Hallo Lina,

      die Variable wird von uns in der Tat nie benutzt, allerdings beschreiben wir sie mit den Ergebnissen des Sendens.
      Bitte die Zeile nicht entfernen, da diese Zeile das Senden der Nachricht auslöst.

      Gruß,
      Marvin