android.media.projection
Les API introduites dans Android 5 (niveau d'API 21) vous permettent de capturer le contenu
d'un appareil s'affiche sous forme de flux multimédia sur lequel vous pouvez lire, enregistrer ou caster
d'autres appareils, tels que des téléviseurs.
Android 14 (niveau d'API 34) introduit le partage d'écran d'application, qui permet aux utilisateurs de partager une seule fenêtre d'application plutôt que l'intégralité de l'écran de l'appareil, quel que soit le mode fenêtrage. Le partage d'écran d'une appli exclut les éléments suivants : barre d'état, barre de navigation, notifications et autres éléments d'UI du système à partir de l'écran partagé, Lorsque le partage d'écran d'une application est utilisé pour capturer une application en plein écran. Seul le contenu de l'appli sélectionnée est partagé.
Le partage d'écran des applications garantit la confidentialité des utilisateurs, augmente leur productivité et améliore le multitâche en permettant aux utilisateurs d'exécuter plusieurs applications tout en limitant le partage de contenu à une seule application.
Trois représentations d'affichage
Une projection multimédia capture le contenu de l'écran d'un appareil ou de la fenêtre d'une application et
projette ensuite l'image capturée sur un écran virtuel qui affiche l'image sur
Un Surface
.
L'application fournit le Surface
au moyen d'un
MediaRecorder
,
SurfaceTexture
ou
ImageReader
, qui consomme
le contenu de l'écran capturé et vous permet de gérer les images affichées
sur le Surface
en temps réel. Vous pouvez sauvegarder les images en tant qu'enregistrement ou les caster.
vers un téléviseur ou un autre appareil.
Affichage réel
Démarrez une session de projection multimédia en obtenant un jeton qui accorde à votre application le
Possibilité de capturer le contenu de l'écran de l'appareil ou de la fenêtre de l'application Le jeton
est représentée par une instance
MediaProjection
.
Utilisez la méthode getMediaProjection()
de la
Service système MediaProjectionManager
pour créer une instance MediaProjection
lorsque vous démarrez une nouvelle activité. Démarrez l'activité avec un intent à partir de
Méthode createScreenCaptureIntent()
pour spécifier un écran
opération de capture:
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());
Écran virtuel
La pièce maîtresse d'une projection multimédia est l'écran virtuel, que vous créez en appelant createVirtualDisplay()
sur une instance MediaProjection
:
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);
Les paramètres width
et height
spécifient les dimensions de l'instance
l'écran. Pour obtenir les valeurs de largeur et de hauteur, utilisez les
API WindowMetrics
introduites
sous Android 11 (niveau d'API 30). Pour en savoir plus, consultez les
section Taille de la projection multimédia.)
Surface
Dimensionnez la surface de projection multimédia pour produire une sortie de la façon appropriée. la résolution de problèmes. Agrandissez la surface (basse résolution) pour caster du contenu sur un écran écrans d'ordinateur et de petite taille (haute résolution) pour l'enregistrement de l'écran d'un appareil.
À partir d'Android 12L (niveau d'API 32), lors de l'affichage du contenu capturé sur la le système adapte le contenu de manière uniforme, afin que les deux dimensions du contenu (largeur et hauteur) soient égales ou inférieures que les dimensions correspondantes de la surface. Le contenu capturé est ensuite centré sur la surface.
L'approche de scaling d'Android 12L améliore la diffusion d'écran sur les téléviseurs et d'autres grands écrans en maximisant la taille de l'image de la surface tout en garantissant au bon format.
Autorisation de service de premier plan
Si votre application cible Android 14 ou une version ultérieure, son fichier manifeste doit inclure un
déclaration d'autorisation pour
Type de service de premier plan mediaProjection
:
<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>
Démarrez le service de projection multimédia en appelant startForeground()
.
Si vous ne spécifiez pas le type de service de premier plan dans l'appel, le type est défini par défaut
à un entier bit à bit des types de services de premier plan définis dans le fichier manifeste. Si
le fichier manifeste ne spécifie aucun type de service, le système génère
MissingForegroundServiceTypeException
Consentement de l'utilisateur
Votre application doit demander le consentement de l'utilisateur avant chaque session de projection multimédia. A
"session" est un appel unique à createVirtualDisplay()
. Un jeton MediaProjection
doit être utilisé une seule fois pour passer l'appel.
Sur Android 14 ou version ultérieure, la méthode createVirtualDisplay()
génère une
SecurityException
si votre
l'application effectue l'une des opérations suivantes:
- Transmet plusieurs fois une instance
Intent
renvoyée parcreateScreenCaptureIntent()
àgetMediaProjection()
. - Appelle
createVirtualDisplay()
plusieurs fois sur le mêmeMediaProjection
. Instance
Taille de projection multimédia
Une projection multimédia peut capturer l'intégralité de l'écran de l'appareil ou la fenêtre d'une application quel que soit le mode de fenêtrage.
Taille initiale
Avec la projection multimédia en plein écran, votre application doit déterminer la taille l'écran de l'appareil. Dans le partage d'écran d'une appli, celle-ci ne pourra pas déterminer la taille de l'écran capturé jusqu'à ce que l'utilisateur sélectionne la région de capture. Ainsi, la taille initiale d'une projection multimédia est la taille de l'écran de l'appareil.
Utiliser la plate-forme WindowManager
méthode getMaximumWindowMetrics()
pour renvoyer une
WindowMetrics
pour
écran de l'appareil, même si l'application hôte de projection multimédia est en mode multifenêtre
et n'occupe qu'une partie de l'écran.
Pour assurer la compatibilité jusqu'au niveau d'API 14, utilisez l'WindowMetricsCalculator
computeMaximumWindowMetrics()
.
de la bibliothèque Jetpack WindowManager
.
Appelez la méthode WindowMetrics
getBounds()
pour obtenir la largeur et la hauteur de l'écran de l'appareil.
Changements de taille
La taille de la projection multimédia peut changer lorsque vous faites pivoter l'appareil. ou bien l'utilisateur sélectionne une fenêtre d'application comme région de capture lors du partage d'écran de l'application. La projection multimédia peut être au format letterbox si le contenu capturé est un de taille différente de celle des métriques de fenêtre maximale obtenues lorsque le média la projection a été configurée.
Pour que la projection multimédia s'aligne précisément sur la taille de l'image capturée
pour chaque zone capturée et lors des rotations d'appareil, utilisez la
Rappel onCapturedContentResize()
pour redimensionner la capture. (Pour plus d'informations
informations, consultez la section Personnalisation ci-dessous).
Personnalisation
Votre application peut personnaliser l'expérience utilisateur de la projection multimédia à l'aide des éléments suivants :
API MediaProjection.Callback
:
onCapturedContentVisibilityChanged()
: Permet à l'application hôte (celle qui a démarré la projection multimédia) d'afficher ou de masquer le contenu partagé.Utilisez ce rappel pour personnaliser l'interface utilisateur de votre application en fonction de la est visible par l'utilisateur. Par exemple, si votre application est visible utilisateur et qui affiche le contenu capturé dans l'interface utilisateur de l'application. application capturée est également visible par l'utilisateur (comme indiqué dans ce ), l'utilisateur voit le même contenu deux fois. Utiliser le rappel pour mettre à jour l'interface utilisateur de votre application pour masquer le contenu capturé et libérer de l'espace de mise en page dans votre pour d'autres contenus.
onCapturedContentResize()
: Permet à l'application hôte de modifier la taille de la projection multimédia sur l'appareil d'affichage et de projection multimédiaSurface
en fonction de la taille de l'élément capturé la région d'affichage.Déclenchement à chaque fois que le contenu capturé est affiché (une fenêtre d'application unique ou complète) l'écran de l'appareil : change de taille (en raison de la rotation de l'appareil ou de la capture l'application qui passe dans un autre mode de fenêtrage). Cette API vous permet de redimensionner la surface et l'écran virtuels pour garantir que le format correspond à celui et que la capture n'est pas au format letterbox.
Récupération des ressources
Votre application doit enregistrer MediaProjection
onStop()
rappel pour être informé lorsque la session de projection multimédia est arrêtée et qu'elle devient
non valide. Lorsque la session est arrêtée, votre application doit libérer les ressources
qu'il contient, comme l'écran virtuel et la surface de projection. A arrêté
la session de projection multimédia ne peut plus créer d'écran virtuel, même si
votre application n'a pas encore créé d'écran virtuel pour cette projection multimédia.
Le rappel est appelé lorsque la projection multimédia se termine, soit parce que le l'utilisateur met fin manuellement à la session, ou parce que le système l'arrête pour une raison quelconque.
Si votre application n'enregistre pas le rappel, tout appel à createVirtualDisplay()
lance
IllegalStateException
Désactiver
Android 14 ou version ultérieure active le partage d'écran des applications par défaut. Chaque support permet aux utilisateurs de partager une fenêtre d'application ou la l'intégralité de l'écran.
Votre application peut désactiver le partage d'écran des applications en appelant la méthode
Méthode createScreenCaptureIntent(MediaProjectionConfig)
avec un argument MediaProjectionConfig
renvoyé par un appel à
createConfigForDefaultDisplay()
Un appel à createScreenCaptureIntent(MediaProjectionConfig)
avec une
L'argument MediaProjectionConfig
renvoyé par un appel à
createConfigForUserChoice()
est identique
comme comportement par défaut, c'est-à-dire un appel
createScreenCaptureIntent()
.
Applications redimensionnables
Vos applications de projection multimédia doivent toujours être redimensionnables (resizeableActivity="true"
). Redimensionnable
sont compatibles avec les modifications de configuration de l'appareil et le mode multifenêtre (voir
Compatibilité avec le mode multifenêtre).
Si votre application n'est pas redimensionnable, elle doit interroger les limites d'affichage dans une fenêtre.
et utiliser getMaximumWindowMetrics()
pour récupérer le WindowMetrics
de
la zone d'affichage maximale disponible pour l'application :
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();
Ressources supplémentaires
Pour en savoir plus sur la projection multimédia, consultez la section Capturer la lecture vidéo et audio.