Medienprojektion

Die android.media.projection Mit den in Android 5 (API-Level 21) eingeführten APIs kannst du Inhalte erfassen des Geräts als Medienstream zum Abspielen, Aufzeichnen oder Streamen andere Geräte wie z. B. Fernseher.

Mit Android 14 (API-Level 34) wird die App-Bildschirmfreigabe eingeführt, mit der Nutzer ein einzelnes App-Fenster und nicht den gesamten Bildschirm Fenstermodus. Bei der App-Bildschirmfreigabe sind die Statusleiste, die Navigationsleiste Benachrichtigungen und andere Elemente der System-UI über den gemeinsam genutzten Bildschirm aus – sogar Die App-Bildschirmfreigabe wird verwendet, um eine App im Vollbildmodus aufzunehmen. Nur der Inhalt der ausgewählten App wird geteilt.

Mit der App-Bildschirmfreigabe werden die Privatsphäre der Nutzer geschützt, die Produktivität gesteigert verbessert Multitasking, indem Nutzern ermöglicht wird, mehrere Apps auszuführen, Inhalte mit nur einer App teilen.

Drei Darstellungen

Eine Medienprojektion erfasst den Inhalt eines Gerätebildschirms oder eines App-Fensters und projiziert das aufgenommene Bild auf ein virtuelles Display, das es Surface.

<ph type="x-smartling-placeholder">
</ph> Das Display eines echten Geräts wird auf das virtuelle Display projiziert. Inhalt von
              virtuelle Anzeige, die auf die von der Anwendung bereitgestellte Surface geschrieben wird. <ph type="x-smartling-placeholder">
</ph> Abbildung 1: Projizierter echter Gerätebildschirm oder App-Fenster virtueller Bildschirm. Virtuelle Anzeige in der Anwendung geschrieben Surface

Die Anwendung stellt die Surface über eine MediaRecorder SurfaceTexture oder ImageReader, wofür Sie den Inhalt der aufgenommenen Anzeige und ermöglicht Ihnen, die gerenderten Bilder am Surface in Echtzeit. Du kannst die Bilder als Aufnahme oder Streaming speichern an einen Fernseher oder ein anderes Gerät übertragen.

Echtes Display

Starten Sie eine Sitzung zur Medienprojektion, indem Sie ein Token abrufen, das Ihrer App die Berechtigung Die Möglichkeit, den Inhalt des Gerätebildschirms oder des App-Fensters zu erfassen. Das Token wird durch eine Instanz des MediaProjection .

Verwenden Sie die Methode getMediaProjection() des MediaProjectionManager-Systemdienst zum Erstellen einer MediaProjection-Instanz wenn Sie eine neue Aktivität starten. Starten Sie die Aktivität mit einem Intent aus der Methode createScreenCaptureIntent() zum Angeben eines Bildschirms Erfassungsvorgang:

Kotlin

val mediaProjectionManager = getSystemService(MediaProjectionManager::class.java)
var mediaProjection : MediaProjection

val startMediaProjection = registerForActivityResult(
    StartActivityForResult()
) { result ->
    if (result.resultCode == RESULT_OK) {
        mediaProjection = mediaProjectionManager
            .getMediaProjection(result.resultCode, result.data!!)
    }
}

startMediaProjection.launch(mediaProjectionManager.createScreenCaptureIntent())

Java

final MediaProjectionManager mediaProjectionManager =
    getSystemService(MediaProjectionManager.class);
final MediaProjection[] mediaProjection = new MediaProjection[1];

ActivityResultLauncher<Intent> startMediaProjection = registerForActivityResult(
    new StartActivityForResult(),
    result -> {
        if (result.getResultCode() == Activity.RESULT_OK) {
            mediaProjection[0] = mediaProjectionManager
                .getMediaProjection(result.getResultCode(), result.getData());
        }
    }
);

startMediaProjection.launch(mediaProjectionManager.createScreenCaptureIntent());

Virtuelle Anzeige

Das Herzstück einer Medienprojektion ist die virtuelle Anzeige, die Sie durch einen Anruf createVirtualDisplay() auf einer MediaProjection-Instanz:

Kotlin

virtualDisplay = mediaProjection.createVirtualDisplay(
                     "ScreenCapture",
                     width,
                     height,
                     screenDensity,
                     DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                     surface,
                     null, null)

Java

virtualDisplay = mediaProjection.createVirtualDisplay(
                     "ScreenCapture",
                     width,
                     height,
                     screenDensity,
                     DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                     surface,
                     null, null);

Die Parameter width und height geben die Dimensionen der virtuellen Display. Um Werte für Breite und Höhe zu erhalten, verwenden Sie die Methode WindowMetrics APIs eingeführt in Android 11 (API-Level 30). (Einzelheiten finden Sie in der Medienprojektionsgröße).

Surface

Die Größe der Projektionsfläche für die Medienprojektion so festlegen, dass die Ausgabe im richtigen Format generiert wird Problembehebung. Mache die Oberfläche groß (niedrige Auflösung) für das Bildschirmstreaming auf Fernseher oder Computermonitore und kleine (hohe Auflösung) für Geräte-Display-Aufzeichnungen.

Ab Android 12L (API-Level 32) werden beim Rendern erfasster Inhalte auf der skaliert das System den Inhalt gleichmäßig, unter Beibehaltung des Seitenverhältnisses sodass beide Abmessungen des Inhalts (Breite und Höhe) gleich oder kleiner sind als die entsprechenden Abmessungen der Oberfläche. Der erfasste Inhalt wird dann zentriert auf der Oberfläche.

Der Skalierungsansatz von Android 12L verbessert die Bildschirmübertragung auf Fernseher und anderen großen Bildschirmen verwenden, indem Sie die Größe des Oberflächenbilds maximieren und gleichzeitig sicherstellen, das richtige Seitenverhältnis.

Berechtigung für Dienste im Vordergrund

Wenn deine App auf Android 14 oder höher ausgerichtet ist, muss das App-Manifest eine Deklaration der Berechtigung für die mediaProjection-Dienst im Vordergrund:

<manifest ...>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
    <application ...>
        <service
            android:name=".MyMediaProjectionService"
            android:foregroundServiceType="mediaProjection"
            android:exported="false">
        </service>
    </application>
</manifest>

Starten Sie den Medienprojektionsdienst mit einem startForeground()-Aufruf.

Wenn Sie den Typ des Diensts im Vordergrund nicht angeben, wird der Typ standardmäßig verwendet. in eine bitweise Ganzzahl der im Manifest definierten Typen von Diensten im Vordergrund. Wenn wenn im Manifest keine Diensttypen angegeben sind, MissingForegroundServiceTypeException.

Ihre App muss vor jeder Sitzung für die Medienprojektion die Nutzereinwilligung einholen. A Sitzung ist ein einzelner Aufruf von createVirtualDisplay(). Ein MediaProjection-Token darf nur einmal für den Aufruf verwendet werden.

Unter Android 14 oder höher löst die Methode createVirtualDisplay() den Fehler SecurityException, wenn Die App führt eine der folgenden Aktionen aus:

  • Übergibt eine Intent-Instanz, die von createScreenCaptureIntent() an getMediaProjection() zurückgegeben wird, mehrmals.
  • createVirtualDisplay() wird am selben MediaProjection mehrmals aufgerufen Instanz

Größe der Medienprojektion

Mit einer Medienprojektion kann das gesamte Display des Geräts oder ein App-Fenster erfasst werden. unabhängig vom Fenstermodus.

Anfangsgröße

Bei einer Vollbild-Medienprojektion muss Ihre App die Größe der Gerätebildschirms. Bei der App-Bildschirmfreigabe kann die App nicht ermitteln, Bildschirmanzeige so lange, bis der Nutzer den Aufnahmebereich ausgewählt hat. Die anfängliche Größe einer Medienprojektion ist also die Größe des Gerätebildschirms.

Plattform WindowManager verwenden getMaximumWindowMetrics()-Methode, um eine WindowMetrics-Objekt für den Bildschirm, auch wenn sich die Host-App für die Medienprojektion im Mehrfenstermodus befindet und nimmt nur einen Teil des Displays ein.

Für Kompatibilität bis hin zum API-Level 14 verwenden Sie die WindowMetricsCalculator computeMaximumWindowMetrics() aus der Jetpack-WindowManager-Bibliothek.

Rufen Sie die Methode WindowMetrics getBounds() auf, um die Breite und Höhe des Gerätedisplays zu erhalten.

Größenänderungen

Die Größe der Medienprojektion kann sich ändern, wenn das Gerät gedreht wird. oder der Nutzer wählt bei der App-Bildschirmfreigabe ein App-Fenster als Aufnahmebereich aus. Die Medienprojektion kann mit Letterbox-Balken versehen sein, wenn der aufgenommene Inhalt eine von den Messwerten für das maximale Fenster abweichen, die Sie erhalten, wenn die Medien Projektion eingerichtet wurde.

Um sicherzustellen, dass die Medienprojektion genau auf die Größe der aufgenommenen Bilder ausgerichtet ist für jeden erfassten Bereich und für alle Geräterotationen, onCapturedContentResize()-Callback, um die Größe der Aufnahme anzupassen. (Weitere finden Sie im Abschnitt Anpassung unten.

Personalisierung

In Ihrer App können Sie die Medienprojektion so anpassen, dass Sie Folgendes tun können: MediaProjection.Callback APIs:

  • onCapturedContentVisibilityChanged(): Ermöglicht der Host-App (die App, die die Medienprojektion gestartet hat) zum Anzeigen oder die geteilten Inhalte ausblenden.

    Verwenden Sie diesen Callback, um die Benutzeroberfläche Ihrer App anzupassen, je nachdem, ob die erfassten Region für den Nutzer sichtbar ist. Wenn Ihre App beispielsweise für Nutzer von Nutzer und zeigt den erfassten Inhalt in der Benutzeroberfläche der App an. die erfasste App auch für den Nutzer sichtbar ist (siehe Callback), sieht der Nutzer denselben Inhalt zweimal. Callback zum Aktualisieren verwenden App-Benutzeroberfläche, um die erfassten Inhalte zu verbergen und Platz in der App zu schaffen, App für andere Inhalte.

  • onCapturedContentResize(): Ermöglicht der Host-App, die Größe der Medienprojektion auf der virtuellen Display- und Medienprojektion Surface basierend auf der Größe der aufgenommenen Anzeigeregion.

    Wird ausgelöst, wenn die erfassten Inhalte – ein einzelnes App-Fenster oder ein voller Inhalt – ausgelöst werden Geräteanzeige: ändert die Größe (aufgrund der Gerätedrehung oder des erfassten App in einen anderen Fenstermodus wechselt). Verwenden Sie diese API, um sowohl die virtuellen Display und Oberfläche, um sicherzustellen, dass das Seitenverhältnis dem aufgenommenen und die Aufnahme wurde nicht mit Letterbox-Balken versehen.

Ressourcenwiederherstellung

Deine App sollte die MediaProjection registrieren onStop() Callback, um informiert zu werden, wenn die Sitzung für die Medienprojektion beendet wird und zu ungültig. Wenn die Sitzung beendet wird, sollte Ihre App die Ressourcen freigeben, die wie die virtuelle Anzeige und die Projektionsfläche. Ein gestopptes Sitzung zur Projektion von Medieninhalten kann keine neue virtuelle Anzeige mehr erstellt werden, selbst wenn Ihre App noch keine virtuelle Anzeige für diese Medienprojektion erstellt hat.

Der Callback wird aufgerufen, wenn die Medienprojektion beendet wird, weil die die Sitzung manuell beendet wird oder weil das System sie irgendetwas begründen.

Wenn deine App den Callback nicht registriert, gilt jeder Aufruf von createVirtualDisplay() Würfe IllegalStateException.

Widerrufen

Unter Android 14 oder höher ist die App-Bildschirmfreigabe standardmäßig aktiviert. Jedes Medium Projektionssitzung können Nutzende ein App-Fenster oder das auf dem gesamten Display.

Deine App kann die App-Bildschirmfreigabe deaktivieren, indem sie die Methode createScreenCaptureIntent(MediaProjectionConfig) mit einem MediaProjectionConfig-Argument, das von einem Aufruf von createConfigForDefaultDisplay()

Ein Anruf von createScreenCaptureIntent(MediaProjectionConfig) mit einem MediaProjectionConfig-Argument, das von einem Aufruf von zurückgegeben wird createConfigForUserChoice() ist identisch Standardverhalten, d. h. ein Aufruf an createScreenCaptureIntent()

Apps mit anpassbarer Größe

Die Größe Ihrer Apps zur Projektion von Medien muss immer veränderbar sein (resizeableActivity="true"). Größenanpassung Apps unterstützen Änderungen der Gerätekonfiguration und den Mehrfenstermodus (siehe Unterstützung des Mehrfenstermodus).

Wenn die Größe Ihrer Anwendung nicht angepasst werden kann, müssen die Anzeigegrenzen von einem Fenster abgefragt werden. und verwenden Sie getMaximumWindowMetrics(), um WindowMetrics von Maximale Anzeigefläche, die der App zur Verfügung steht :

Kotlin

val windowContext = context.createWindowContext(context.display!!,
      WindowManager.LayoutParams.TYPE_APPLICATION, null)
val projectionMetrics = windowContext.getSystemService(WindowManager::class.java)
      .maximumWindowMetrics

Java

Context windowContext = context.createWindowContext(context.getDisplay(),
      WindowManager.LayoutParams.TYPE_APPLICATION, null);
WindowMetrics projectionMetrics = windowContext.getSystemService(WindowManager.class)
      .getMaximumWindowMetrics();

Weitere Informationen

Weitere Informationen zur Medienprojektion finden Sie unter Video- und Audiowiedergabe aufnehmen