Benutzerdefinierte Schnelleinstellungen-Kacheln für Ihre App erstellen

Schnelleinstellungen sind Kacheln, die im Schnelleinstellungsfeld angezeigt werden und Aktionen darstellen. Nutzer können darauf tippen, um wiederkehrende Aufgaben schnell zu erledigen. Ihre App kann Nutzern über die Klasse TileService eine benutzerdefinierte Kachel zur Verfügung stellen und den Status der Kachel mit einem Tile-Objekt verfolgen. Sie können beispielsweise eine Kachel erstellen, mit der Nutzer ein von Ihrer App bereitgestelltes VPN aktivieren oder deaktivieren können.

Schnelleinstellungen mit aktivierter und deaktivierter VPN-Kachel
Abbildung 1: Schnelleinstellungen-Leiste mit aktivierter und deaktivierter VPN-Kachel.

Entscheiden, wann eine Kachel erstellt werden soll

Wir empfehlen, Kacheln für bestimmte Funktionen zu erstellen, auf die Nutzer häufig oder schnell zugreifen müssen (oder beides). Die effektivsten Kacheln erfüllen beide Kriterien und bieten schnellen Zugriff auf häufig ausgeführte Aktionen.

Sie könnten beispielsweise eine Kachel für eine Fitness-App erstellen, mit der Nutzer schnell ein Training starten können. Wir raten jedoch davon ab, eine Kachel für dieselbe App zu erstellen, über die Nutzer ihren gesamten Trainingsverlauf aufrufen können.

Anwendungsfälle für Fitness-App-Kacheln
Abbildung 2. Beispiele für empfohlene und nicht empfohlene Kacheln für eine Fitness-App.

Damit Ihre Kachel besser gefunden wird und einfacher zu verwenden ist, empfehlen wir, Folgendes zu vermeiden:

  • Verwenden Sie keine Kacheln zum Starten einer App. Verwenden Sie stattdessen eine App-Verknüpfung oder einen Standard-Launcher.

  • Vermeiden Sie die Verwendung von Kacheln für einmalige Nutzeraktionen. Verwenden Sie stattdessen ein App-Kürzel oder eine Benachrichtigung.

  • Vermeiden Sie es, zu viele Kacheln zu erstellen. Wir empfehlen maximal zwei pro App. Verwenden Sie stattdessen eine App-Verknüpfung.

  • Vermeiden Sie die Verwendung von Kacheln, auf denen Informationen angezeigt werden, die für Nutzer aber nicht interaktiv sind. Verwenden Sie stattdessen eine Benachrichtigung oder ein Widget.

Tile erstellen

Wenn Sie eine Kachel erstellen möchten, müssen Sie zuerst ein entsprechendes Kachelsymbol erstellen und dann die TileService in der Manifestdatei Ihrer App erstellen und deklarieren.

Das Beispiel für Schnelleinstellungen enthält ein Beispiel dafür, wie eine Kachel erstellt und verwaltet wird.

Benutzerdefiniertes Symbol erstellen

Sie müssen ein benutzerdefiniertes Symbol angeben, das auf dem Kachel im Bereich „Schnelleinstellungen“ angezeigt wird. Sie fügen dieses Symbol hinzu, wenn Sie die TileService deklarieren, wie im nächsten Abschnitt beschrieben. Das Symbol muss einfarbig weiß mit transparentem Hintergrund sein, eine Größe von 24 × 24 dp haben und im Format VectorDrawable vorliegen.

Beispiel für ein Vektor-Drawable
Abbildung 3: Beispiel für ein Vektor-Drawable.

Erstellen Sie ein Symbol, das visuell auf den Zweck der Kachel hinweist. So können Nutzer leichter erkennen, ob die Kachel ihren Anforderungen entspricht. Sie könnten beispielsweise ein Stoppuhrsymbol für eine Kachel für eine Fitness-App erstellen, mit der Nutzer ein Training starten können.

TileService erstellen und deklarieren

Erstellen Sie einen Dienst für Ihre Kachel, der die Klasse TileService erweitert.

Kotlin

class MyQSTileService: TileService() {

  // Called when the user adds your tile.
  override fun onTileAdded() {
    super.onTileAdded()
  }
  // Called when your app can update your tile.
  override fun onStartListening() {
    super.onStartListening()
  }

  // Called when your app can no longer update your tile.
  override fun onStopListening() {
    super.onStopListening()
  }

  // Called when the user taps on your tile in an active or inactive state.
  override fun onClick() {
    super.onClick()
  }
  // Called when the user removes your tile.
  override fun onTileRemoved() {
    super.onTileRemoved()
  }
}

Java

public class MyQSTileService extends TileService {

  // Called when the user adds your tile.
  @Override
  public void onTileAdded() {
    super.onTileAdded();
  }

  // Called when your app can update your tile.
  @Override
  public void onStartListening() {
    super.onStartListening();
  }

  // Called when your app can no longer update your tile.
  @Override
  public void onStopListening() {
    super.onStopListening();
  }

  // Called when the user taps on your tile in an active or inactive state.
  @Override
  public void onClick() {
    super.onClick();
  }

  // Called when the user removes your tile.
  @Override
  public void onTileRemoved() {
    super.onTileRemoved();
  }
}

Deklarieren Sie TileService in der Manifestdatei Ihrer App. Fügen Sie den Namen und das Label von TileService, dem benutzerdefinierten Symbol, das Sie im vorherigen Abschnitt erstellt haben, sowie die entsprechende Berechtigung hinzu.

 <service
     android:name=".MyQSTileService"
     android:exported="true"
     android:label="@string/my_default_tile_label"  // 18-character limit.
     android:icon="@drawable/my_default_icon_label"
     android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
     <intent-filter>
         <action android:name="android.service.quicksettings.action.QS_TILE" />
     </intent-filter>
 </service>

TileService verwalten

Nachdem Sie Ihre TileService erstellt und im App-Manifest deklariert haben, müssen Sie ihren Status verwalten.

TileService ist ein gebundener Dienst. Ihr TileService wird gebunden, wenn Ihre App dies anfordert oder wenn das System mit ihm kommunizieren muss. Ein typischer Lebenszyklus eines gebundenen Dienstes enthält die folgenden vier Callback-Methoden: onCreate(), onBind(), onUnbind() und onDestroy(). Diese Methoden werden vom System aufgerufen, wenn der Dienst in eine neue Lebenszyklusphase eintritt.

Übersicht über den Lebenszyklus von TileService

Zusätzlich zu den Callbacks, die den Lebenszyklus des gebundenen Dienstes steuern, müssen Sie andere Methoden implementieren, die für den TileService-Lebenszyklus spezifisch sind. Diese Methoden können außerhalb von onCreate() und onDestroy() aufgerufen werden, da die Service-Lebenszyklusmethoden und die TileService-Lebenszyklusmethoden in zwei separaten asynchronen Threads aufgerufen werden.

Der TileService-Lebenszyklus enthält die folgenden Methoden, die vom System aufgerufen werden, wenn Ihr TileService in eine neue Lebenszyklusphase eintritt:

  • onTileAdded(): Diese Methode wird nur aufgerufen, wenn der Nutzer Ihre Kachel zum ersten Mal hinzufügt und wenn der Nutzer Ihre Kachel entfernt und wieder hinzufügt. Dies ist der beste Zeitpunkt für die einmalige Initialisierung. Dies reicht jedoch möglicherweise nicht für die erforderliche Initialisierung aus.

  • onStartListening() und onStopListening(): Diese Methoden werden immer dann aufgerufen, wenn Ihre App die Kachel aktualisiert. Das geschieht häufig. Die TileService bleibt zwischen onStartListening() und onStopListening() gebunden, sodass deine App die Kachel ändern und Updates senden kann.

  • onTileRemoved(): Diese Methode wird nur aufgerufen, wenn der Nutzer Ihre Kachel entfernt.

Zuhörmodus auswählen

Ihr TileService hört im aktiven oder nicht aktiven Modus zu. Wir empfehlen, den aktiven Modus zu verwenden, den Sie im App-Manifest deklarieren müssen. Andernfalls ist TileService der Standardmodus und muss nicht deklariert werden.

Gehen Sie nicht davon aus, dass Ihr TileService außerhalb des Methodenpaars onStartListening() und onStopListening() liegt.

Verwenden Sie den Aktivmodus für ein TileService, das in seinem eigenen Prozess auf Ereignisse wartet und seinen Status überwacht. Eine TileService im aktiven Modus ist für onTileAdded(), onTileRemoved(), Tippereignisse und bei Bedarf für den App-Prozess gebunden.

Wir empfehlen den aktiven Modus, wenn Ihr TileService benachrichtigt wird, wenn der Kachelstatus durch einen eigenen Prozess aktualisiert werden soll. Aktive Kacheln belasten das System weniger, da sie nicht jedes Mal gebunden werden müssen, wenn das Schnelleinstellungen-Panel für den Nutzer sichtbar wird.

Die statische Methode TileService.requestListeningState() kann aufgerufen werden, um den Start des Zuhörmodus anzufordern und einen Callback an onStartListening() zu erhalten.

Sie können den aktiven Modus deklarieren, indem Sie der Manifestdatei Ihrer App META_DATA_ACTIVE_TILE hinzufügen.

<service ...>
    <meta-data android:name="android.service.quicksettings.ACTIVE_TILE"
         android:value="true" />
    ...
</service>

Nicht aktiver Modus

Der nicht aktive Modus ist der Standardmodus. Ein TileService befindet sich im nicht aktiven Modus, wenn es gebunden ist, während Ihre Kachel für den Nutzer sichtbar ist. Das bedeutet, dass Ihr TileService möglicherweise zu Zeiten, die außerhalb Ihrer Kontrolle liegen, neu erstellt und gebunden wird. Sie kann auch entbunden und zerstört werden, wenn der Nutzer die Kachel nicht sieht.

Ihre App erhält einen Callback an onStartListening(), nachdem der Nutzer das Schnelleinstellungen-Panel geöffnet hat. Sie können Ihr Tile-Objekt zwischen onStartListening() und onStopListening() beliebig oft aktualisieren.

Sie müssen den nicht aktiven Modus nicht deklarieren. Fügen Sie einfach META_DATA_ACTIVE_TILE nicht in die Manifestdatei Ihrer App ein.

Kachelstatus – Übersicht

Nachdem ein Nutzer Ihre Kachel hinzugefügt hat, befindet sie sich immer in einem der folgenden Zustände.

  • STATE_ACTIVE: Gibt an, dass der Status „Ein“ oder „Aktiviert“ ist. Der Nutzer kann in diesem Status mit Ihrer Kachel interagieren.

    Bei einer Kachel für eine Fitness-App, über die Nutzer ein zeitgesteuertes Training starten können, würde STATE_ACTIVE beispielsweise bedeuten, dass der Nutzer ein Training gestartet hat und der Timer läuft.

  • STATE_INACTIVE: Gibt einen deaktivierten oder pausierten Status an. Der Nutzer kann in diesem Status mit Ihrer Kachel interagieren.

    Wenn wir das Beispiel der Kachel für Fitness-Apps noch einmal aufgreifen, bedeutet eine Kachel in STATE_INACTIVE, dass der Nutzer noch kein Training gestartet hat, dies aber tun könnte.

  • STATE_UNAVAILABLE: Gibt einen vorübergehend nicht verfügbaren Status an. Der Nutzer kann in diesem Status nicht mit Ihrer Kachel interagieren.

    Wenn beispielsweise eine Kachel in STATE_UNAVAILABLE angezeigt wird, ist sie aus irgendeinem Grund derzeit nicht für den Nutzer verfügbar.

Das System legt nur den Anfangsstatus Ihres Tile-Objekts fest. Sie legen den Status des Tile-Objekts für den Rest seines Lebenszyklus fest.

Das System kann das Kachelsymbol und den Hintergrund tönen, um den Status Ihres Tile-Objekts widerzuspiegeln. Tile-Objekte, die auf STATE_ACTIVE festgelegt sind, sind am dunkelsten, während STATE_INACTIVE und STATE_UNAVAILABLE immer heller werden. Der genaue Farbton ist je nach Hersteller und Version unterschiedlich.

VPN-Kachel mit Farbton, der den Objektstatus widerspiegelt
Abbildung 4: Beispiele für eine Kachel, die entsprechend dem Kachelstatus (aktiv, inaktiv und nicht verfügbar) eingefärbt ist.

Kachel aktualisieren

Sie können die Kachel aktualisieren, sobald Sie einen Rückruf an onStartListening() erhalten. Je nach Modus der Kachel kann sie mindestens einmal aktualisiert werden, bis ein Callback an onStopListening() erfolgt.

Im aktiven Modus können Sie Ihre Kachel genau einmal aktualisieren, bevor Sie einen Callback an onStopListening() erhalten. Im nicht aktiven Modus können Sie Ihre Kachel zwischen onStartListening() und onStopListening() beliebig oft aktualisieren.

Sie können Ihr Tile-Objekt abrufen, indem Sie getQsTile() aufrufen. Wenn Sie bestimmte Felder des Tile-Objekts aktualisieren möchten, rufen Sie die folgenden Methoden auf:

Sie müssen updateTile() aufrufen, um die Kachel zu aktualisieren, nachdem Sie die Felder des Tile-Objekts auf die richtigen Werte festgelegt haben. Dadurch werden die aktualisierten Kacheldaten vom System geparst und die Benutzeroberfläche wird aktualisiert.

Kotlin

data class StateModel(val enabled: Boolean, val label: String, val icon: Icon)

override fun onStartListening() {
  super.onStartListening()
  val state = getStateFromService()
  qsTile.label = state.label
  qsTile.contentDescription = tile.label
  qsTile.state = if (state.enabled) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
  qsTile.icon = state.icon
  qsTile.updateTile()
}

Java

public class StateModel {
  final boolean enabled;
  final String label;
  final Icon icon;

  public StateModel(boolean e, String l, Icon i) {
    enabled = e;
    label = l;
    icon = i;
  }
}

@Override
public void onStartListening() {
  super.onStartListening();
  StateModel state = getStateFromService();
  Tile tile = getQsTile();
  tile.setLabel(state.label);
  tile.setContentDescription(state.label);
  tile.setState(state.enabled ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
  tile.setIcon(state.icon);
  tile.updateTile();
}

Taps verarbeiten

Nutzer können auf Ihre Kachel tippen, um eine Aktion auszulösen, wenn sich Ihre Kachel in STATE_ACTIVE oder STATE_INACTIVE befindet. Das System ruft dann den onClick()-Callback Ihrer App auf.

Sobald Ihre App einen Callback an onClick() erhält, kann sie ein Dialogfeld oder eine Aktivität starten, Hintergrundaufgaben auslösen oder den Status der Kachel ändern.

Kotlin

var clicks = 0
override fun onClick() {
  super.onClick()
  counter++
  qsTile.state = if (counter % 2 == 0) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
  qsTile.label = "Clicked $counter times"
  qsTile.contentDescription = qsTile.label
  qsTile.updateTile()
}

Java

int clicks = 0;

@Override
public void onClick() {
  super.onClick();
  counter++;
  Tile tile = getQsTile();
  tile.setState((counter % 2 == 0) ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
  tile.setLabel("Clicked " + counter + " times");
  tile.setContentDescription(tile.getLabel());
  tile.updateTile();
}

Dialogfeld öffnen

showDialog() minimiert den Bereich mit den Schnelleinstellungen und zeigt ein Dialogfeld an. Verwenden Sie einen Dialog, um Ihrer Aktion Kontext hinzuzufügen, wenn zusätzliche Eingaben oder eine Nutzereinwilligung erforderlich sind.

Aktivität starten

startActivityAndCollapse() startet eine Aktivität und minimiert gleichzeitig das Steuerfeld. Aktivitäten sind nützlich, wenn detailliertere Informationen als in einem Dialogfeld angezeigt werden sollen oder wenn Ihre Aktion sehr interaktiv ist.

Wenn Ihre App eine erhebliche Nutzerinteraktion erfordert, sollte sie nur im Notfall eine Aktivität starten. Verwenden Sie stattdessen ein Dialogfeld oder einen Schalter.

Wenn der Nutzer lange auf eine Kachel tippt, wird der Bildschirm App-Info angezeigt. Wenn Sie dieses Verhalten überschreiben und stattdessen eine Aktivität zum Festlegen von Einstellungen starten möchten, fügen Sie einer Ihrer Aktivitäten mit ACTION_QS_TILE_PREFERENCES ein <intent-filter> hinzu.

Ab Android-API 28 muss die PendingIntent die Intent.FLAG_ACTIVITY_NEW_TASK haben:

if (Build.VERSION.SDK_INT >= 28) {
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}

Alternativ können Sie das Flag im Abschnitt Activity in AndroidManifest.xml hinzufügen.

Kachel als umschaltbar markieren

Wir empfehlen, die Kachel als umschaltbar zu kennzeichnen, wenn sie hauptsächlich als Schalter mit zwei Zuständen fungiert (was das häufigste Verhalten von Kacheln ist). So können Informationen zum Verhalten der Kachel an das Betriebssystem weitergegeben und die allgemeine Barrierefreiheit verbessert werden.

Setzen Sie die Metadaten TOGGLEABLE_TILE auf true, um die Kachel als umschaltbar zu kennzeichnen.

<service ...>
  <meta-data android:name="android.service.quicksettings.TOGGLEABLE_TILE"
    android:value="true" />
</service>

Nur sichere Aktionen auf sicher gesperrten Geräten ausführen

Ihre Kachel wird möglicherweise auf gesperrten Geräten über dem Sperrbildschirm angezeigt. Wenn die Kachel vertrauliche Informationen enthält, prüfen Sie den Wert von isSecure(), um festzustellen, ob sich das Gerät in einem sicheren Zustand befindet. Ihr TileService sollte sein Verhalten entsprechend ändern.

Wenn die Kachelaktion sicher ausgeführt werden kann, während das Gerät gesperrt ist, verwenden Sie startActivity(), um eine Aktivität über dem Sperrbildschirm zu starten.

Wenn die Kachelaktion unsicher ist, verwenden Sie unlockAndRun(), um den Nutzer aufzufordern, sein Gerät zu entsperren. Bei Erfolg führt das System das Runnable-Objekt aus, das Sie an diese Methode übergeben.

Nutzer auffordern, Ihre Kachel hinzuzufügen

Wenn Nutzer Ihre Kachel manuell hinzufügen möchten, müssen sie mehrere Schritte ausführen:

  1. Wische nach unten, um den Bereich „Schnelleinstellungen“ zu öffnen.
  2. Tippen Sie auf die Schaltfläche „Bearbeiten“.
  3. Bitte sie, auf ihrem Gerät durch alle Kacheln zu scrollen, bis sie deine Kachel finden.
  4. Halten Sie die Kachel gedrückt und ziehen Sie sie in die Liste der aktiven Kacheln.

Der Nutzer kann Ihre Kachel auch jederzeit verschieben oder entfernen.

Ab Android 13 können Sie die Methode requestAddTileService() verwenden, um Nutzern das Hinzufügen Ihrer Kachel zu einem Gerät zu erleichtern. Bei dieser Methode werden Nutzer aufgefordert, Ihre Kachel schnell direkt zu ihren Schnelleinstellungen hinzuzufügen. Der Prompt enthält den Anwendungsnamen, das bereitgestellte Label und das Symbol.

Eingabeaufforderung für die Quick Settings Placement API
Abbildung 5. Aufforderung für die Quick Settings Placement API.
public void requestAddTileService (
  ComponentName tileServiceComponentName,
  CharSequence tileLabel,
  Icon icon,
  Executor resultExecutor,
  Consumer<Integer> resultCallback
)

Der Callback enthält Informationen dazu, ob die Kachel hinzugefügt wurde, nicht hinzugefügt wurde, bereits vorhanden war oder ob ein Fehler aufgetreten ist.

Es liegt in Ihrem Ermessen, wann und wie oft Sie Nutzer auffordern. Wir empfehlen, requestAddTileService() nur im Kontext aufzurufen, z. B. wenn der Nutzer zum ersten Mal mit einer Funktion interagiert, die über deine Kachel möglich ist.

Das System kann die Verarbeitung von Anfragen für ein bestimmtes ComponentName beenden, wenn der Nutzer es zuvor oft genug abgelehnt hat. Der Nutzer wird anhand des Context ermittelt, der zum Abrufen dieses Dienstes verwendet wird. Er muss mit dem aktuellen Nutzer übereinstimmen.