Unterstützung für verbundene Displays

Verbundene Displays erweitern die Desktop-Freiform-Fenster auf Standard-Smartphones, sodass Nutzer über ihre Mobilgeräte auf große Bildschirme zugreifen können. Diese Funktion eröffnet neue Möglichkeiten für die App-Interaktion und die Nutzerproduktivität.

Alle einzigartigen Funktionen des Desktop-Freiform-Fensters gelten auch für verbundene Displays. Wenn Sie ein Smartphone mit einem Display verbinden, bleibt der Status des Smartphones unverändert und auf dem verbundenen Display wird eine leere Desktop-Sitzung gestartet. Das Gerät und das Display fungieren als zwei separate Systeme mit jeweils eigenen Apps.

Abbildung 1. Smartphone, das mit einem externen Display verbunden ist, auf dem eine Desktopsitzung angezeigt wird, während das Smartphone seinen eigenen Status beibehält.

Wenn Sie ein Gerät mit Desktop-Freiform-Fenster, z. B. ein Tablet, mit einem externen Monitor verbinden, wird die Desktopsitzung auf beide Displays erweitert. Die beiden Displays funktionieren dann als ein zusammenhängendes System. Bei dieser Einrichtung können Fenster, Inhalte und der Cursor frei zwischen den beiden Displays bewegt werden.

Abbildung 2. Tablet, das mit einem externen Monitor verbunden ist, wobei die Desktopsitzung auf beide Displays erweitert wird.

Damit verbundene Displays effektiv unterstützt werden, müssen Sie mehrere Aspekte des Designs und der Implementierung Ihrer App berücksichtigen. Die folgenden Best Practices sorgen für eine reibungslose und produktive Nutzererfahrung.

Umgang mit dynamischen Displayänderungen

Viele Apps werden unter der Annahme entwickelt, dass sich das Display-Objekt und seine Eigenschaften während des Lebenszyklus der App nicht ändern. Wenn ein Nutzer jedoch einen externen Monitor anschließt oder trennt oder ein App-Fenster zwischen Displays verschiebt, kann sich das zugrunde liegende Display-Objekt ändern, das mit dem Kontext oder Fenster Ihrer App verknüpft ist. Die Eigenschaften des Displays, z. B. Größe, Auflösung, Aktualisierungsrate, HDR-Unterstützung und Dichte, können unterschiedlich sein. Wenn du beispielsweise Werte basierend auf dem Display des Smartphones hartcodierst, werden deine Layouts auf einem externen Display wahrscheinlich nicht richtig dargestellt.

Externe Displays können auch sehr unterschiedliche Pixeldichten haben. Sie müssen dafür sorgen, dass Ihre App korrekt auf Änderungen der Pixeldichte reagiert. Dazu gehören die Verwendung von dichteunabhängigen Pixeln (dp) für Layouts, die Bereitstellung von dichteabhängigen Ressourcen und die entsprechende Skalierung der Benutzeroberfläche.

Wenn eine Aktivität auf einem externen Display ausgeführt wird, während die Verbindung zum Display getrennt wird, verschiebt das System die Aktivität auf das Hauptdisplay. Das Verschieben löst Konfigurationsänderungen aus, z. B. Änderungen der Bildschirmgröße und -dichte, die dazu führen können, dass die Aktivität neu erstellt wird. Ihre App muss die Konfigurationsänderung verarbeiten, indem sie den UI-Status speichert und wiederherstellt, um Datenverlust oder eine verwirrende Nutzererfahrung zu vermeiden.

Den richtigen Kontext verwenden

In Umgebungen mit mehreren Displays ist es wichtig, den richtigen Kontext zu verwenden. Beim Zugriff auf Ressourcen unterscheidet sich der Aktivitätskontext (der angezeigt wird) vom Anwendungskontext (der nicht angezeigt wird).

Der Aktivitätskontext enthält Informationen zum Display und wird immer an den Displaybereich angepasst, in dem die Aktivität angezeigt wird. So erhalten Sie die richtigen Informationen zur Anzeigedichte oder zu den Fenstermesswerten Ihrer App. Verwenden Sie immer den Aktivitätskontext (oder einen anderen UI-basierten Kontext), um Informationen zum aktuellen Fenster oder Display zu erhalten. Dies wirkt sich auch auf einige System-APIs aus, die Informationen aus dem Kontext verwenden.

In Jetpack Compose können Sie mit CompositionLocal-Objekten wie LocalConfiguration.current und LocalDensity.current auf displayspezifische Informationen zugreifen. Wenn eine Aktivität oder ein Fenster zwischen Displays verschoben wird, ändert sich die Gerätekonfiguration, was eine Neuzusammensetzung mit neuen Displaymesswerten auslöst. CompositionLocal-Objekte ermöglichen eine nahtlose Anpassung der Benutzeroberfläche.

Displayinformationen abrufen

Mit der Klasse Display kannst du Informationen wie Displaygröße, Pixeldichte oder Flags abrufen. Verwenden Sie den Systemdienst DisplayManager, um die verfügbaren Displays abzurufen. Wenn du externe Displays identifizieren möchtest, filtere Display.DEFAULT_DISPLAY heraus. Das ist normalerweise das integrierte Smartphone- oder Tablet-Display:

val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val displays = displayManager.getDisplays()
// The default display is 0. External displays have other IDs.
val externalDisplays = displays.filter { it.displayId != Display.DEFAULT_DISPLAY }

Start und Konfiguration von Aktivitäten verwalten

Bei verbundenen Displays können Apps festlegen, auf welchem Display eine App ausgeführt werden soll, wenn sie gestartet wird oder wenn sie eine andere Aktivität erstellt. Dieses Verhalten hängt vom Startmodus der Aktivität ab, der in der Manifestdatei definiert ist, sowie von den Intent-Flags und Optionen, die von der Entität festgelegt wurden, die die Aktivität startet.

Wenn eine Aktivität auf ein sekundäres Display verschoben wird, kann es in Ihrer App zu einer Kontextaktualisierung, einer Größenänderung des Fensters sowie zu Konfigurations- und Ressourcenänderungen kommen. Wenn die Aktivität die Konfigurationsänderung verarbeitet, wird sie in onConfigurationChanged() benachrichtigt. Andernfalls wird die Aktivität neu gestartet.

Wenn der ausgewählte Startmodus für eine Aktivität mehrere Instanzen zulässt, kann beim Starten auf einem sekundären Bildschirm eine neue Instanz der Aktivität erstellt werden. Beide Aktivitäten werden gleichzeitig fortgesetzt, was für bestimmte Multitasking-Szenarien von Vorteil sein kann.

Mit ActivityOptions kannst du eine Aktivität auf einem bestimmten Display starten. Für launchDisplayId ist Android 8 (API-Level 26) oder höher erforderlich.

// Get DisplayManager and find the first external display.
val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val externalDisplayId = displayManager.displays
    .firstOrNull { it.displayId != Display.DEFAULT_DISPLAY }
    ?.displayId

// If an external display is found, launch the activity on it.
if (externalDisplayId != null) {
    val intent = Intent(this, MySecondaryActivity::class.java)
    val options = ActivityOptions.makeBasic()
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        options.launchDisplayId = externalDisplayId
    }
    startActivity(intent, options.toBundle())
} else {
    // Optionally, handle the case where no external display is connected.
}

Zulassungslisten für Geräte vermeiden

In Apps werden die Benutzeroberfläche und Funktionen für große Bildschirme manchmal auf bestimmte Geräte beschränkt, indem eine Zulassungsliste verwendet oder BUILD.MODEL und die integrierte Displaygröße geprüft werden. Dieser Ansatz ist für verbundene Displays nicht effektiv, da praktisch jedes Gerät mit einem großen Bildschirm verbunden werden kann und sich das Gerätemodell nicht ändert, wenn ein externes Display verbunden wird.

Anstatt Zulassungslisten zu verwenden oder BUILD.MODEL und die integrierte Displaygröße zu prüfen, solltest du zur Laufzeit Fenstermesswerte oder Gerätefunktionen prüfen, um Entscheidungen zur Benutzeroberfläche zu treffen. Verwenden Sie Jetpack WindowManager APIs oder Fenstergrößenklassen, um responsive und adaptive Layouts für verschiedene Bildschirmgrößen und ‑dichten zu erstellen.

Unterstützung externer Peripheriegeräte

Wenn Nutzer eine Verbindung zu einem externen Display herstellen, erstellen sie oft eine desktopähnliche Umgebung. Dazu werden häufig externe Tastaturen, Mäuse, Trackpads, Webcams, Mikrofone und Lautsprecher verwendet. Sie müssen dafür sorgen, dass Ihre App nahtlos mit diesen Peripheriegeräten funktioniert. Dazu gehören die Verarbeitung von Tastenkombinationen, die Verwaltung von Mauszeigerinteraktionen, die korrekte Unterstützung externer Kameras oder Mikrofone und die Berücksichtigung des Audioausgaberoutings. Weitere Informationen finden Sie unter Eingabekompatibilität auf großen Bildschirmen.

Nutzerproduktivität steigern

Verbundene Displays bieten eine hervorragende Möglichkeit, die Produktivität der Nutzer zu verbessern. Sie haben jetzt die Tools, um mobile Apps zu entwickeln, die mit Desktopanwendungen vergleichbar sind. Sie können die folgenden Funktionen implementieren, um die Nutzerproduktivität zu steigern:

  • Ermögliche Nutzern, mehrere Instanzen derselben App zu öffnen. Das ist besonders nützlich, wenn sie Dokumente vergleichen, verschiedene Unterhaltungen verwalten oder mehrere Dateien gleichzeitig ansehen möchten.
  • Ermögliche Nutzern, Rich-Daten per Drag-and-drop in und aus deiner App zu teilen.
  • Implementiere ein robustes Zustandsverwaltungssystem, damit Nutzer ihren Workflow auch bei Konfigurationsänderungen beibehalten können.

Wenn Sie diese Richtlinien befolgen und die bereitgestellten Codebeispiele verwenden, können Sie Apps erstellen, die sich nahtlos an verbundene Displays anpassen und Nutzern eine umfassendere und produktivere Umgebung bieten.