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
.
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
Nutzereinwilligung
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 voncreateScreenCaptureIntent()
angetMediaProjection()
zurückgegeben wird, mehrmals. createVirtualDisplay()
wird am selbenMediaProjection
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 MedienprojektionSurface
basierend auf der Größe der aufgenommenen Anzeigeregion.Wird ausgelöst, wenn der erfasste Inhalt – ein einzelnes App-Fenster oder ein voller Inhalt – ausgelöst wird 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