Android 5'te (API seviyesi 21) kullanıma sunulan android.media.projection
API'leri, bir cihaz ekranının içeriğini oynatıp kaydedebileceğiniz veya TV gibi diğer cihazlara yayınlayabileceğiniz bir medya akışı olarak yakalamanızı sağlar.
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ı kullanıma sunar. Uygulama ekran paylaşımı, bir uygulamayı tam ekranda yakalamak için kullanıldığında bile durum çubuğunu, gezinme çubuğunu, bildirimleri ve diğer sistem kullanıcı arayüzü öğelerini paylaşılan ekrandan hariç tutar. Yalnızca seçilen uygulamanın içerikleri paylaşılır.
Uygulama ekranı paylaşımı, kullanıcı gizliliğini sağlar, kullanıcı üretkenliğini artırır ve kullanıcıların birden fazla uygulamayı çalıştırmasına olanak tanıyarak ancak içerik paylaşımını tek bir uygulamayla kısıtlayarak çoklu görev özelliğini iyileştirir.
Üç görüntülü reklam temsili
Medya projeksiyonu, bir cihaz ekranının veya uygulama penceresinin içeriğini yakalar ve ardından yakalanan görüntüyü Surface
üzerinde görüntüleyen sanal bir ekrana yansıtır.
Uygulama, yakalanan ekranın içeriklerini kullanan ve Surface
'te oluşturulan resimleri anlık olarak yönetmenize olanak tanıyan bir MediaRecorder
, SurfaceTexture
veya ImageReader
aracılığıyla Surface
'yi sağlar. Resimleri kayıt olarak kaydedebilir veya TV'ye ya da başka bir cihaza yayınlayabilirsiniz.
Gerçek ekran
Uygulamanıza cihaz ekranının veya uygulama penceresinin içeriğini yakalama olanağı tanıyan bir jeton alarak medya projeksiyon 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
sistem hizmetinin getMediaProjection()
yöntemini kullanın. Ekran görüntüsü işlemini belirtmek için etkinliği createScreenCaptureIntent()
yönteminden bir intent ile 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 ana unsuru, MediaProjection
örneğinde createVirtualDisplay()
çağrısı yaparak oluşturduğunuz 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 projeksiyon boyutu bölümüne bakın.)
Yüzey
Medya projeksiyon yüzeyini, uygun çözünürlükte çıkış oluşturacak şekilde boyutlandırın. TV'lere veya bilgisayar monitörlerine ekran yayınlamak için yüzeyi büyük (düşük çözünürlüklü) ve cihaz ekranı kaydı için küçük (yüksek çözünürlüklü) yapın.
Android 12L (API düzeyi 32) itibarıyla, yakalanan içeriği yüzeyde oluştururken sistem, en boy oranını koruyarak içeriği eşit şekilde ölçeklendirir. Böylece içeriğin her iki boyutu da (genişlik ve yükseklik) yüzeyin ilgili boyutlarına eşit veya bu boyutlardan daha küçük olur. Daha sonra çekilen içerik yüzeyin ortasına yerleştirilir.
Android 12L ölçeklendirme yaklaşımı, yüzey resminin boyutunu en üst düzeye çıkarırken doğru en boy oranını sağlayarak televizyonlara ve diğer büyük ekranlara ekran yayınlamayı iyileştirir.
Ön plan hizmeti izni
Uygulamanız Android 14 veya sonraki sürümleri hedefliyorsa uygulama manifest dosyasında mediaProjection
ön plan hizmet 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()
adresine çağrı yaparak medya projeksiyon hizmetini başlatın.
Çağrıda ön plan hizmet türünü belirtmezseniz tür, varsayılan olarak manifest'de tanımlanan ön plan hizmet türlerinin bitlik bir tam sayısı olur. Manifest'te herhangi bir hizmet türü belirtilmezse sistem MissingForegroundServiceTypeException
hatası verir.
Kullanıcı rızası
Uygulamanız her medya projeksiyon oturumundan önce kullanıcı izni istemelidir. Oturum, createVirtualDisplay()
'a 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 yapıyorsa createVirtualDisplay()
yöntemi SecurityException
hatası verir:
createScreenCaptureIntent()
kaynağından döndürülen birIntent
örneğinigetMediaProjection()
kaynağına birden fazla kez iletir- Aynı
MediaProjection
örneğindecreateVirtualDisplay()
işlevini birden fazla kez çağırır.
Medya projeksiyonu 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 içi ekran paylaşımında, kullanıcı yakalama bölgesini seçene kadar uygulamanız yakalanan ekranın boyutunu belirleyemez. Bu nedenle, herhangi bir medya projeksiyonunun ilk boyutu cihaz ekranının boyutudur.
Medya projeksiyonu ana makinesi uygulaması çoklu pencere modunda olsa ve ekranın yalnızca bir kısmını kaplasa bile cihaz ekranı için bir WindowMetrics
nesnesi döndürmek üzere platform WindowManager
getMaximumWindowMetrics()
yöntemini kullanı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
Cihaz döndürüldüğünde veya kullanıcı, uygulama ekranı paylaşımında yakalama bölgesi olarak bir uygulama penceresi seçtiğinde medya projeksiyonunun boyutu değişebilir. Kaydedilen içerik, medya projeksiyonu ayarlanırken elde edilen maksimum pencere metriklerinden farklı bir boyuta sahipse medya projeksiyonu sinemaskoplu olabilir.
Medya projeksiyonunun, yakalanan tüm bölgelerde ve cihaz döndürmelerinde yakalanan içeriğin boyutuyla tam olarak hizalandığından emin olmak için yakalamayı yeniden boyutlandırmak üzere onCapturedContentResize()
geri çağırma işlevini 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'leriyle medya projeksiyonu kullanıcı deneyimini özelleştirebilir:
onCapturedContentVisibilityChanged()
: Barındıran uygulamanı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ı tarafından görülebilmesine göre özelleştirmek için bu geri çağırma işlevini kullanın. Örneğin, uygulamanız kullanıcı tarafından görülebilir durumdaysa ve yakalanan içeriği uygulamanın kullanıcı arayüzünde gösteriyorsa ve yakalanan uygulama da kullanıcı tarafından görülebilir durumdaysa (bu geri çağırma aracılığıyla belirtildiği gibi) kullanıcı aynı içeriği iki kez görür. Uygulamanızın kullanıcı arayüzünü güncellemek için geri çağırma işlevini kullanarak yakalanan içeriği gizleyin ve uygulamanızdaki düzen alanında diğer içerikler için yer açın.
onCapturedContentResize()
: Ana makine uygulamasının, yakalanan ekran bölgesinin boyutuna göre sanal ekrandaki medya projeksiyonunun ve medya projeksiyonuSurface
boyutunu değiştirmesine olanak tanır.Yakalanan içerik (tek bir uygulama penceresi veya cihazın tamamının ekranı) boyut değiştirdiğinde (cihazın döndürülmesi veya yakalanan uygulamanın farklı bir pencere moduna girmesi nedeniyle) tetiklenir. En boy oranının yakalanan içerikle eşleştiğinden ve yakalamanın sinemaskop olmadığından emin olmak için hem sanal ekranı hem de yüzeyi yeniden boyutlandırmak üzere bu API'yi kullanın.
Kaynak kurtarma
Uygulamanız, medya projeksiyon oturumu durdurulduğunda ve geçersiz hale geldiğinde bilgilendirilmek için MediaProjection
onStop()
geri çağırma işlevini kaydetmelidir. Oturum durdurulduğunda uygulamanız, sanal ekran ve projeksiyon yüzeyi gibi sahip olduğu kaynakları serbest bırakmalıdır. Uygulamanız daha önce bu medya projeksiyonu için sanal ekran oluşturmamış olsa bile durdurulan medya projeksiyonu oturumu artık yeni bir sanal ekran oluşturamaz.
Sistem, medya projeksiyonu sona erdiğinde geri çağırma işlevini çağırır. Bu fesih, aşağıdakiler gibi çeşitli nedenlerden kaynaklanabilir:
- Kullanıcı, uygulamanın kullanıcı arayüzünü veya sistemin medya projeksiyonu durum çubuğu çipini kullanarak oturumu durdurur
- Ekran kilitleniyor
- Başka bir medya projeksiyonu oturumu başlar
- Uygulama işlemi sonlandırılır.
Uygulamanız geri aramayı kaydetmezse createVirtualDisplay()
numaralı telefona yapılan tüm aramalar IllegalStateException
hatası verir.
Devre dışı bırak
Android 14 veya sonraki sürümler, uygulama ekranı paylaşımını varsayılan olarak etkinleştirir. 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 bir MediaProjectionConfig
bağımsız değişkeniyle createScreenCaptureIntent(MediaProjectionConfig)
yöntemini ç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şkeni içeren createScreenCaptureIntent(MediaProjectionConfig)
çağrısı, varsayılan davranışla (yani createScreenCaptureIntent()
çağrısı) aynıdır.
Yeniden boyutlandırılabilir uygulamalar
Medya projeksiyon uygulamalarınızı her zaman yeniden boyutlandırılabilir yapın (resizeableActivity="true"
). Yeniden boyutlandırılabilir uygulamalar, cihaz yapılandırması değişikliklerini ve çoklu pencere modunu destekler (Çoklu pencere desteği bölümüne bakın).
Uygulamanız yeniden boyutlandırılamıyorsa görüntüleme sınırlarını bir pencere bağlamında sorgulamalı ve uygulamanın kullanabileceği maksimum görüntüleme 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
Ekran yansıtma istismarlarında, kullanıcılar cihaz ekranlarının paylaşıldığını fark etmediğinden finansal bilgiler gibi gizli kullanıcı verileri açığa çıkar.
Android 15 (API düzeyi 35) ve sonraki sürümlerde, devam eden ekran yansıtma işlemleri hakkında kullanıcıları uyarmak için büyük ve belirgin bir durum çubuğu çipi gösterilir. Kullanıcılar, ekranlarının paylaşılmasını, aktarılmasını veya kaydedilmesini engellemek için çipe dokunabilir. Ayrıca, cihaz ekranı kilitlendiğinde ekran yansıtma otomatik olarak durdurulur.
Ekran paylaşımı, yayınlama veya kayıt başlatarak medya projeksiyonu durum çubuğu çipinin kullanılabilirliğini test edin. Çip, durum çubuğunda görünür.
Ekran yansıtma, kullanıcının durum çubuğu çipiyle etkileşime geçmesi veya kilit ekranının etkinleştirilmesi nedeniyle durdurulduğunda uygulamanızın kaynakları serbest bırakmasını ve kullanıcı arayüzünü güncellemesini sağlamak için aşağıdakileri yapın:
MediaProjection.Callback
örneği oluşturun.Geri çağırma
onStop()
yöntemini uygulayın. Ekran yansıtma durdurulduğunda bu yöntem çağrılır. Uygulamanızın kullandığı tüm kaynakları serbest bırakın ve uygulama kullanıcı arayüzünü gerektiği gibi güncelleyin.
Geri aramayı 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.