Watchface Projekt Konfiguration

Category: 

Um ein Android™ Watchface zu erstellen, wird sowohl eine Wearable App, als auch eine Handheld App benötigt. Die Wearable App enthält dabei ein oder mehrere Watchfaces und kann bei Bedarf auch Einstellungsmenüs enthalten. Die Handheld App wird benötigt, da User eine App nicht direkt auf das Wearable Gerät herunterladen, sondern diese mit einer Handy-App gebündelt wird. Wenn nun die Handheld App installiert wird, so wird automatisch auch die Wearable App auf dem Wearable installiert.

Dieses Tutorial zeigt, wie man ein neues Android Projekt erstellt und dieses so konfiguriert, dass man Watchfaces implementieren kann.

Projekt erstellen

Die folgenden Schritte zeigen, wie man mit Android Studio ein entsprechendes Projekt erstellt. 

  • Android Studio starten
  • Neues Projekt starten ("Start a new Android Studio project")
    • Name festlegen (z.B. SampleWatch)
    • Company Name angeben
      • Aus diesem und dem Namen der App wird ein entsprechendes Package erzeugt
      • Aus der Domain wearable.example.com und dem Projektnamen SampleWatch wird beispielsweise das Package com.example.wearable.samplewatch erzeugt
    • Bei Bedarf kann hier auch der Speicherort des Projekts geändert werden
  • Klick auf Next
    • Das Häkchen bei "Phone and Tablet" muss gesetzt sein
      • Android Wear wird erst ab der API Version 18 unterstützt, daher muss als minimales SDK diese Version gewählt werden
    • Bei Wear muss ebenfalls ein Haken gesetzt sein
      • Hier muss jedoch die Version 21 gewählt werden, da die Watchface API erst mit Lollipop gekommen ist
  • Klick auf Next
    • Für die Mobile-App wähle "Add No Activity" aus
  • Klick auf Next
    • Für die Wearable App wird ebenfalls "Add No Activity" gewählt
  • Klick auf Finish

Nun heißt es einen Augenblick warten, während Android Studio das Projekt erstellt.

Berechtigungen erteilen

Watchfaces benötigen die Berechtigungen PROVIDE_BACKGROUND und WAKE_LOCK. Um diese zu erteilen, müssen wir die manifest-Datei bearbeiten.

Alle Berechtigungen der Wearable App müssen auch in der Handheld App gespeichert werden!

Die Datei befindet sich jeweils im Unterordner manifests und heißt AndroidManifest.xml
Die folgenden Zeilen müssen in beide Datei nach dem manifest-Tag eingefügt werden:

<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

Die AndroidManifest.xml Datei der Wearable App sieht nun in etwa so aus:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.infectedbytes.example.watchface.samplewatch">

    <uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <uses-feature android:name="android.hardware.type.watch" />
    <application android:allowBackup="true" android:label="@string/app_name"
       android:icon="@drawable/ic_launcher" android:theme="@android:style/Theme.DeviceDefault">

    </application>
</manifest>

Watchface implementieren

Um nun ein Watchface zu implementieren, muss eine neue Klasse erstellt werden, welche von CanvasWatchFaceService erbt und in der onCreateEngine Methode eine Engine zurückgibt.

public class SampleWatchfaceService extends CanvasWatchFaceService {
    @Override
    public Engine onCreateEngine() {
        return new Engine();
    }

    private class Engine extends CanvasWatchFaceService.Engine {
        @Override
        public void onCreate(SurfaceHolder holder) {
            super.onCreate(holder);
            // initialisiere Watch Face
            // lade Bilder, erstelle Paint-Objekte, ...
        }

        @Override
        public void onPropertiesChanged(Bundle properties) {
            super.onPropertiesChanged(properties);
            // erhalte device features
            // z.B. burn-in protection und low-bit ambientmode
        }

        @Override
        public void onTimeTick() {
            super.onTimeTick();
            // Timer ist abgelaufen
            // aktualisiere Uhrzeit, erzwinge ggf. neuzeichnen
        }

        @Override
        public void onAmbientModeChanged(boolean inAmbientMode) {
            super.onAmbientModeChanged(inAmbientMode);
            // Wechsel zwischen den Modi
        }

        @Override
        public void onDraw(Canvas canvas, Rect bounds) {
            // Hier wird die eigentliche Uhr gezeichnet
        }

        @Override
        public void onVisibilityChanged(boolean visible) {
            super.onVisibilityChanged(visible);
            // Sichtbarkeit wurde geändert
        }
    }
}

Eine beispielhafte Implementierung findet ihr unter anderem in meinem Folgepost.

Immer wenn eine Änderung eintritt, z.B. wenn die Zeitzone sich ändert oder beim TimerTick, sollte die Uhr neu gezeichnet werden. Dies erledigt man am einfachsten, indem man an entsprechenden Punkten die invalidate Methode aufruft.

Watchface Service registrieren

Damit das Watchface auch auf der Uhr und der Companion App ausgewählt werden kann, muss es noch als Service im Manifest eingetragen werden.
Dazu wird wieder die AndroidManifest.xml Datei der Wearable App geöffnet und das application Tag um folgenden Code erweitert:

<service
   android:name=".SampleWatchfaceService"
   android:label="SampleWatchface"
   android:allowEmbedded="true"
   android:taskAffinity=""
   android:permission="android.permission.BIND_WALLPAPER" >
  <meta-data
   android:name="android.service.wallpaper"
   android:resource="@xml/watch_face" />
  <meta-data
   android:name="com.google.android.wearable.watchface.preview"
   android:resource="@drawable/preview" />
  <meta-data
   android:name="com.google.android.wearable.watchface.preview_circular"
   android:resource="@drawable/preview_circular" />
  <intent-filter>
    <action android:name="android.service.wallpaper.WallpaperService" />
    <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
  </intent-filter>
</service>

Da das Manifest nun auf mehrere Dateien verweist, welche nicht existieren, werden die entsprechenden Einträge rot markiert.
Als erstes kümmern wir uns nun um die fehlende xml-Datei. Diese sollte am besten im xml Ordner landen. Da dieser jedoch noch nicht existieren erstellen wir diesen noch.

In diesem Ordner erzeugen wir eine neue Datei. Am einfachsten geht dies durch einen Rechtsklick auf den neu erstellten Ordner -> New -> File.
Als Namen geben wir watch_face.xml ein und klicken auf OK.
In diese Datei kopieren wir nun den folgenden Code:

<?xml version="1.0" encoding="UTF-8"?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android" />

Damit werden nur noch zwei Zeilen des Manifests rot markiert. Diese Zeilen geben an, welche Bilder bei der Watchface Auswahl als Vorschau verwendet werden sollen.
Der Resourcen-String gibt an, dass sich die Bilder (preview und preview_circular) im Ordner drawable befinden.

Verschiebt oder kopiert nun die Bilder in den drawable Ordner. Die Bilder sind typischerweise 320x320 Pixel groß.
Solange euer Watchface noch nicht fertig ist, könnt ihr erstmal diese Bilder verwenden:

Falls sich die Darstellung der runden Uhr nicht wesentlich von der eckigen Uhr unterscheidet, kann man den gesamten meta-data Eintrag der runden Uhr (preview_circular) und damit auch das runde Bild weglassen.

Sobald euer Watchface fertig ist, könnt ihr die Platzhalter durch richtige Vorschaubilder ersetzen. Startet dazu euer Watchface auf einem Emulator und macht einen Screenshot.
Schneidet diesen zurecht und kopiert in in den drawable Ordner.

Mit Hilfe der Companion App, kann man auch Wearable Screenshots machen. Dazu auf den Menü-Button oben-rechts drücken und dort auf "Wearable-Screenshot erstellen".

Kompilieren und ausführen

Nun sind wir soweit, unser Watchface auszuführen. Dazu müssen wir als erstes den richtigen Build-Typ festlegen. Da wir nicht die Handheld App, sondern die Wearable App starten wollen, müssen wir diese auswählen:

Anschließend können wir auf den Playbutton direkt daneben klicken.
Daraufhin öffnet sich ein Dialog in dem wir bei Bedarf zusätzliche Einstellungen vornehmen können. Standardmäßig möchte Android Studio die Default Activity starten.
Da wir jedoch ein Watchface entwickeln und dieses als Service realisiert wird, gibt es keine Default Activity. Dementsprechend wählen wir "Do not launch Activity" und klicken auf Run.
Nun wird das Projekt kompiliert und nach kurzer Zeit öffnet sich ein Dialog, welcher uns auffordert ein Gerät auszuwählen. Falls ihr noch keinen Emulator gestartet habt, könnt ihr dies per Klick auf "Launch Emulator" machen.
Nachdem ihr das passende Gerät ausgewählt habt, wird das neue Watchface auf die Uhr übertragen. Dies kann wieder einige Sekunden dauern. Anschließend können wir unser neu erstelltes Watchface auf der Uhr auswählen und bewundern.
Da wir die draw Methode noch nicht implementiert haben, sehen wir allerdings nur einen schwarzen Bildschirm.

Gratulation! Ihr habt euer erstes Watchface erstellt!

Wie ihr seht, ist es gar nicht so schwer ein Watchface Projekt zu erstellen und zu konfigurieren. Falls ihr Fragen oder Anregungen habt, hinterlasst gerne einen Kommentar.