Android 5'te (API düzeyi 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ı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ı 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çeriği 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 işlevini iyileştirir.
Üç görüntülü reklam temsili
Medya yansıtma, 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, Surface
'yi MediaRecorder
, SurfaceTexture
veya ImageReader
aracılığıyla sağlar. Bu API'ler, yakalanan ekranın içeriğini tüketir ve Surface
'de oluşturulan resimleri gerçek zamanlı olarak yönetmenizi 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 yakalama 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]; 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());
Sanal ekran
Medya projeksiyonunun ana unsuru, MediaProjection
örneğinde createVirtualDisplay()
çağırarak 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()
'dangetMediaProjection()
'ye döndürülen birIntent
örneğini 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 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 boyuttaysa 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()
: Ana 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 görüntü bölgesinin boyutuna göre sanal ekrandaki medya projeksiyonunun ve medya projeksiyonuSurface
boyutunu değiştirmesini sağlar.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 bir 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 yansıtma 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ıyla) 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) QPR1, büyük ve belirgin bir yeni durum çubuğu çipi sunar. Bu çip, kullanıcıları devam eden ekran yansıtma işlemleri konusunda uyarır. Kullanıcılar, ekranlarının paylaşılmasını, aktarılmasını veya kaydedilmesini durdurmak için çipe dokunabilir.
Android 15 QPR1 ve sonraki sürümlerde, cihaz ekranı kilitlendiğinde ekran yansıtma otomatik olarak durdurulur.
Ek kaynaklar
Medya yansıtma hakkında daha fazla bilgi için Video ve ses oynatmayı yakalama başlıklı makaleyi inceleyin.