Android 5'te (API düzeyi 21) kullanıma sunulan android.media.projection API'leri, cihaz ekranının içeriğini oynatabileceğiniz, kaydedebileceğiniz veya TV gibi diğer cihazlara yayınlayabileceğiniz bir medya akışı olarak yakalamanıza olanak tanır.
Android 14 (API düzeyi 34), kullanıcıların pencere modundan bağımsız olarak cihaz ekranının tamamı yerine tek bir uygulama penceresini paylaşmasına olanak tanıyan uygulama ekranı paylaşımını sunar. Uygulama ekran paylaşımında, tam ekran modunda bir uygulamayı yakalamak için uygulama ekran paylaşımı kullanılsa bile durum çubuğu, gezinme çubuğu, bildirimler ve diğer sistem kullanıcı arayüzü öğeleri paylaşılan ekrana dahil edilmez. Yalnızca seçilen uygulamanın içerikleri paylaşılır.
Uygulama ekranı paylaşımı, kullanıcı gizliliğini sağlar, kullanıcı verimliliğini artırır ve kullanıcıların birden fazla uygulamayı çalıştırmasına ancak içerik paylaşımını tek bir uygulamayla sınırlamasına olanak tanıyarak çoklu görev özelliğini geliştirir.
Üç görüntülü reklam temsili
Medya yansıtma, cihaz ekranının veya uygulama penceresinin içeriğini yakalar ve ardından yakalanan görüntüyü Surface üzerinde oluşturulan sanal bir ekrana yansıtır.
Surface konumuna yazılan sanal ekran.
Uygulama, Surface içeriğini MediaRecorder, SurfaceTexture veya ImageReader aracılığıyla sağlar. Bu araçlar, yakalanan ekranın içeriğini tüketir ve Surface üzerinde oluşturulan görüntüleri gerçek zamanlı olarak yönetmenize olanak tanır. Görüntüleri kayıt olarak kaydedebilir veya TV'ye ya da başka bir cihaza aktarabilirsiniz.
Gerçek ekran
Uygulamanıza cihaz ekranının veya uygulama penceresinin içeriğini yakalama olanağı veren bir jeton alarak medya projeksiyonu oturumu başlatın. Jeton, MediaProjection sınıfının bir örneğiyle temsil edilir.
Yeni bir etkinlik başlattığınızda MediaProjection örneği oluşturmak için MediaProjectionManager sisteme ait hizmetinin getMediaProjection() yöntemini kullanın. Ekran görüntüsü alma işlemini belirtmek için createScreenCaptureIntent() yönteminden bir amaçla etkinliği başlatın:
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];
ActivityResultLauncherstartMediaProjection = registerForActivityResult( new StartActivityForResult(), result -> { if (result.getResultCode() == Activity.RESULT_OK) { mediaProjection[0] = mediaProjectionManager .getMediaProjection(result.getResultCode(), result.getData()); } } );
startMediaProjection.launch(mediaProjectionManager.createScreenCaptureIntent());
Sanal ekran
Medya projeksiyonunun temel bileşeni, MediaProjection örneğinde createVirtualDisplay() çağrılarak oluşturulan sanal ekrandır:
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);
width ve height parametreleri, sanal ekranın boyutlarını belirtir. Genişlik ve yükseklik değerlerini almak için Android 11'de (API düzeyi 30) kullanıma sunulan WindowMetrics API'lerini kullanın. (Ayrıntılar için Medya yansıtma boyutu bölümüne bakın.)
Configuration#densityDpi kullanın.
Yüzey
Medya projeksiyon yüzeyini, uygun çözünürlükte çıkış üretecek şekilde boyutlandırın. TV'lere veya bilgisayar monitörlerine ekran yayını yapmak için yüzeyi büyük (düşük çözünürlük), cihaz ekranı kaydı için ise küçük (yüksek çözünürlük) yapın.
Android 12L (API düzeyi 32) itibarıyla, yakalanan içerik yüzeyde oluşturulurken sistem, en boy oranını koruyarak içeriği eşit şekilde ölçeklendirir. Böylece içeriğin her iki boyutu (genişlik ve yükseklik), yüzeyin ilgili boyutlarına eşit veya daha küçük olur. Ardından, yakalanan içerik yüzeyde ortalanır.
Android 12L'deki ölçeklendirme yaklaşımı, yüzey görüntüsünün boyutunu en üst düzeye çıkarırken doğru en boy oranını koruyarak televizyonlara ve diğer büyük ekranlara ekran yayını yapmayı iyileştirir.
Ön plan hizmeti izni
Uygulamanız Android 14 veya sonraki bir sürümü hedefliyorsa uygulama manifestinde mediaProjection ön plan hizmeti türü için izin beyanı bulunmalıdır:
<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>
startForeground() ile yapılan bir çağrıyla medya projeksiyonu hizmetini başlatın.
Çağrıda ön plan hizmeti türünü belirtmezseniz tür, manifestte tanımlanan ön plan hizmeti türlerinin bit düzeyinde tamsayısı olarak varsayılır. Manifest herhangi bir hizmet türü belirtmiyorsa sistem MissingForegroundServiceTypeException istisnası oluşturur.
Kullanıcı rızası
Uygulamanız, her medya projeksiyonu oturumundan önce kullanıcı izni istemelidir. Oturum, createVirtualDisplay()'ya yapılan tek bir çağrıdır. Arama yapmak için MediaProjection jetonu yalnızca bir kez kullanılmalıdır.
Android 14 veya sonraki sürümlerde, uygulamanız aşağıdakilerden birini yaparsa createVirtualDisplay() yöntemi SecurityException oluşturur:
Intentörneğini,createScreenCaptureIntent()'den döndürülengetMediaProjection()'ye birden fazla kez iletiyor.- Aynı
MediaProjectionörneğindecreateVirtualDisplay()işlevi birden fazla kez çağrılıyor.
Medya projeksiyon boyutu
Medya yansıtma, pencere modundan bağımsız olarak cihaz ekranının tamamını veya bir uygulama penceresini yakalayabilir.
İlk boyut
Tam ekran medya yansıtma özelliğinde uygulamanız cihaz ekranının boyutunu belirlemelidir. Uygulama ekran paylaşımında, kullanıcı yakalama bölgesini seçene kadar uygulamanız yakalanan ekranın boyutunu belirleyemez. Bu nedenle, herhangi bir medya yansıtma işleminin başlangıç boyutu, cihaz ekranının boyutudur.
Medya yansıtma ana makine uygulaması çoklu pencere modunda olsa ve ekranın yalnızca bir bölümünü kaplasa bile cihaz ekranı için WindowManager getMaximumWindowMetrics() yöntemini kullanarak WindowMetrics nesnesi döndürün.
API seviyesi 14'e kadar uyumluluk için Jetpack WindowManager
kitaplığındaki WindowMetricsCalculator
computeMaximumWindowMetrics() yöntemini kullanın.
Cihaz ekranının genişliğini ve yüksekliğini almak için WindowMetrics getBounds() yöntemini çağırın.
Boyut değişiklikleri
Medya yansıtma boyutu, cihaz döndürüldüğünde veya kullanıcı uygulama ekranı paylaşımında yakalama bölgesi olarak bir uygulama penceresi seçtiğinde değişebilir. Yakalanan içerik, medya yansıtma ayarlanırken elde edilen maksimum pencere metriklerinden farklı bir boyuttaysa medya yansıtma, sinemaskop şeklinde olabilir.
Medya projeksiyonunun, yakalanan tüm bölgelerdeki ve cihaz döndürmelerindeki yakalanan içeriğin boyutuyla tam olarak eşleşmesini sağlamak için yakalamayı yeniden boyutlandırmak üzere onCapturedContentResize() geri çağırmasını kullanın. (Daha fazla bilgi için aşağıdaki Özelleştirme bölümüne bakın.)
Özelleştirme
Uygulamanız, aşağıdaki MediaProjection.Callback API'lerle medya yansıtma kullanıcı deneyimini özelleştirebilir:
onCapturedContentVisibilityChanged(): Ana makine uygulamasının (medya yansıtmayı başlatan uygulama) paylaşılan içeriği göstermesini veya gizlemesini sağlar.Uygulamanızın kullanıcı arayüzünü, yakalanan bölgenin kullanıcıya görünür olup olmamasına göre özelleştirmek için bu geri çağırmayı kullanın. Örneğin, uygulamanız kullanıcıya görünür durumdaysa ve yakalanan içeriği uygulamanın kullanıcı arayüzünde gösteriyorsa ve yakalanan uygulama da kullanıcıya görünür durumdaysa (bu geri çağırma yoluyla belirtildiği gibi) kullanıcı aynı içeriği iki kez görür. Geri çağırmayı kullanarak uygulamanızın kullanıcı arayüzünü güncelleyin. Böylece, yakalanan içerik gizlenir ve uygulamanızda diğer içerikler için yer açılır.
onCapturedContentResize(): Ana makine uygulamasının, sanal ekrandaki medya projeksiyonunun ve medya projeksiyonununSurfaceboyutunu, yakalanan ekran bölgesinin boyutuna göre değiştirmesine olanak tanır.Yakalanan içerik (tek bir uygulama penceresi veya tam cihaz ekranı) boyut değiştirdiğinde (cihaz döndürüldüğünde ya da yakalanan uygulama farklı bir pencereli görüntüleme moduna girdiğinde) tetiklenir. En boy oranının yakalanan içerikle eşleşmesini ve yakalamanın sinemaskop şeklinde olmamasını sağlamak için hem sanal ekranı hem de yüzeyi yeniden boyutlandırmak üzere bu API'yi kullanın.
Kaynak kurtarma
Uygulamanız, medya projeksiyonu oturumu durdurulduğunda ve geçersiz hale geldiğinde bilgilendirilmek için MediaProjection onStop() geri çağırmasını kaydetmelidir. Oturum durdurulduğunda uygulamanız, sanal ekran ve projeksiyon yüzeyi gibi tuttuğu kaynakları serbest bırakmalıdır. Daha önce uygulamanız bu medya yansıtma için sanal ekran oluşturmamış olsa bile durdurulan medya yansıtma oturumları artık yeni bir sanal ekran oluşturamaz.
Sistem, medya projeksiyonu sonlandırıldığında geri çağırmayı başlatır. Bu fesih, aşağıdakiler gibi çeşitli nedenlerden kaynaklanabilir:
- Kullanıcı, uygulamanın kullanıcı arayüzünü veya sistemin medya yansıtma durum çubuğu çipini kullanarak oturumu durdurduğunda
- ekran kilitleniyorsa
- başka bir medya yansıtma oturumu başlatılırsa
- Uygulama işlemi sonlandırılırsa
Uygulamanız geri aramayı kaydetmezse createVirtualDisplay() numarasına yapılan tüm aramalar IllegalStateException istisnası oluşturur.
Devre dışı bırak
Android 14 veya sonraki sürümlerde uygulama ekranı paylaşımı varsayılan olarak etkindir. Her medya yansıtma oturumunda kullanıcılara bir uygulama penceresini veya ekranın tamamını paylaşma seçeneği sunulur.
Uygulamanız, createConfigForDefaultDisplay() çağrısından döndürülen createScreenCaptureIntent(MediaProjectionConfig) yöntemini MediaProjectionConfig bağımsız değişkeniyle çağırarak uygulama ekranı paylaşımını devre dışı bırakabilir.
createConfigForUserChoice() çağrısından döndürülen MediaProjectionConfig bağımsız değişkeniyle createScreenCaptureIntent(MediaProjectionConfig) çağrısı, varsayılan davranışla aynıdır. Yani createScreenCaptureIntent() çağrısıdır.
Yeniden boyutlandırılabilir uygulamalar
Medya yansıtma uygulamalarınızı her zaman yeniden boyutlandırılabilir hale getirin
(resizeableActivity="true"). Yeniden boyutlandırılabilir uygulamalar, cihaz yapılandırması değişikliklerini ve çoklu pencere modunu destekler (bkz. Çoklu pencere desteği).
Uygulamanız yeniden boyutlandırılamıyorsa ekran sınırlarını bir pencere bağlamından sorgulamalı ve uygulamaya sunulan maksimum ekran alanının WindowMetrics değerini almak için getMaximumWindowMetrics() kullanmalıdır :
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();
Durum çubuğu çipi ve otomatik durdurma
Screen projection exploits expose private user data such as financial information because users don't realize their device screen is being shared.
For apps running on devices with Android 15 QPR1 or higher, a status bar chip that is large and prominent alerts users to any in‑progress screen projection. Users can tap the chip to stop their screen from being shared, cast, or recorded. Also, screen projection automatically stops when the device screen is locked.
Ekran paylaşımı, yayın veya kayıt başlatarak medya projeksiyonu durum çubuğu çipinin kullanılabilirliğini test edin. Çip, durum çubuğunda görünür.
Uygulamanızın, ekran projeksiyonu kullanıcı etkileşimiyle (durum çubuğu çipiyle etkileşim veya kilit ekranı etkinleştirme) durdurulduğunda kaynakları serbest bıraktığından ve kullanıcı arayüzünü güncellediğinden emin olmak için aşağıdakileri yapın:
MediaProjection.Callbackörneği oluşturun.Geri çağırma
onStop()yöntemini uygulayın. Bu yöntem, ekran projeksiyonu durduğunda çağrılır. Uygulamanızın tuttuğu tüm kaynakları serbest bırakın ve gerektiğinde uygulama kullanıcı arayüzünü güncelleyin.
Geri çağırmayı test etmek için durum çubuğu çipine dokunun veya ekran yansıtmayı durdurmak için cihaz ekranını kilitleyin. onStop() yönteminin çağrıldığını ve uygulamanızın amaçlandığı şekilde yanıt verdiğini doğrulayın.
Ek kaynaklar
Medya yansıtma hakkında daha fazla bilgi için Video ve ses oynatmayı kaydetme başlıklı makaleyi inceleyin.