Android 5'te (API düzeyi 21) kullanıma sunulan android.media.projection
API'leri, bir cihaz ekranının içeriğini medya akışı olarak yakalamanızı sağlar. Bu API'leri oynatabilir, kaydedebilir veya TV gibi diğer cihazlara yayınlayabilirsiniz.
Android 14 (API düzeyi 34), kullanıcıların pencere modundan bağımsız olarak tüm cihaz ekranı yerine tek bir uygulama penceresini paylaşmalarını sağlayan uygulama ekranı paylaşımını kullanıma sundu. Uygulama ekran paylaşımında durum çubuğu, gezinme çubuğu, bildirimler ve diğer sistem kullanıcı arayüzü öğeleri, bir uygulamayı tam ekran olarak yakalamak için kullanılsa bile paylaşılan ekrandan hariç tutulur. Yalnızca seçilen uygulamanın içeriği paylaşılır.
Uygulama ekran paylaşımı, kullanıcıların birden fazla uygulamayı çalıştırmasını sağlarken içerik paylaşımını tek bir uygulamayla kısıtlayarak kullanıcı gizliliğini korur, kullanıcı verimliliğini artırır ve çoklu görev deneyimini iyileştirir.
Üç ekran temsili
Medya projeksiyonu, bir cihaz ekranının veya uygulama penceresinin içeriğini yakalar ve daha sonra, yakalanan görüntüyü Surface
'da oluşturan sanal bir ekrana yansıtır.
Uygulama, Surface
öğelerini MediaRecorder
, SurfaceTexture
veya ImageReader
aracılığıyla sağlar. Bu da, yakalanan ekranın içeriğini tüketen ve Surface
üzerinde oluşturulan görüntüleri gerçek zamanlı olarak yönetebilmenizi sağlar. Resimleri kayıt olarak kaydedebilir veya TV'ye ya da başka bir cihaza yayınlayabilirsiniz.
Gerçek görüntülü reklam
Uygulamanıza cihaz ekranının veya uygulama penceresinin içeriklerini yakalama olanağı veren bir jeton alarak bir 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 bir MediaProjection
örneği oluşturmak için MediaProjectionManager
sistem hizmetinin getMediaProjection()
yöntemini kullanın. Bir ekran görüntüsü alma işlemi belirtmek için etkinliği createScreenCaptureIntent()
yönteminden bir niyetle 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 görüntü
Medya projeksiyonunun en önemli kısmı, MediaProjection
örneğinde createVirtualDisplay()
yöntemini ç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 elde etmek için Android 11'de (API düzeyi 30) kullanıma sunulan WindowMetrics
API'lerini kullanın. (Ayrıntılar için Medya projeksiyonu boyutu bölümüne bakın.)
Yüzey
Uygun çözünürlükte çıktı üretmek için medya projeksiyon yüzeyini boyutlandırın. TV'lere veya bilgisayar monitörlerine yayın yaparken yüzeyi büyük (düşük çözünürlüklü), cihaz ekranı kaydı için ise küçük (yüksek çözünürlüklü) kullanın.
Android 12L'den (API düzeyi 32) itibaren sistem, yakalanan içeriği yüzeyde oluştururken 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 karşılık gelen boyutlarına eşit veya bundan daha düşük olur. Yakalanan içerik daha sonra yüzeyde ortalanır.
Android 12L ölçeklendirme yaklaşımı, uygun en boy oranını sağlarken yüzey görüntüsünün boyutunu en üst düzeye çıkararak televizyonlara ve diğer büyük ekranlara ekran yayınını iyileştirir.
Ön plan hizmeti izni
Uygulamanız Android 14 veya sonraki bir sürümü hedefliyorsa uygulama manifesti mediaProjection
ön plan hizmet türü için izin beyanı içermelidir:
<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>
Medya projeksiyonu hizmetini startForeground()
çağrısıyla başlatın.
Çağrıda ön plan hizmet türünü belirtmezseniz tür için varsayılan olarak manifest'te tanımlanan ön plan hizmet türlerinin bit tabanlı bir tam sayısı kullanılır. Manifest herhangi bir hizmet türü belirtmiyorsa sistem MissingForegroundServiceTypeException
değerini döndürür.
Kullanıcı izni
Uygulamanız her medya projeksiyonu oturumundan önce kullanıcı izni istemelidir. Bir oturum, createVirtualDisplay()
öğesine yapılan tek bir çağrıdır. MediaProjection
jetonu, çağrı yapmak için 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
döndürür:
createScreenCaptureIntent()
öğesindengetMediaProjection()
hedefine birden fazla kez döndürülenIntent
örneğini iletircreateVirtualDisplay()
numaralı telefonu aynıMediaProjection
örneğinde birden çok kez çağırır
Medya projeksiyonu boyutu
Bir medya projeksiyonu, aralık modundan bağımsız olarak cihaz ekranının tamamını veya bir uygulama penceresini yakalayabilir.
Başlangıç boyutu
Tam ekran medya projeksiyonu kullanıldığında, uygulamanızın cihaz ekranının boyutunu belirlemesi gerekir. Uygulama ekran paylaşımında, kullanıcı yakalama bölgesini seçene kadar uygulamanız yakalanan ekranın boyutunu belirleyemez. Dolayısıyla, herhangi bir medya projeksiyonunun ilk boyutu cihaz ekranının boyutudur.
Medya projeksiyonu ana makine uygulaması, ekranın yalnızca bir kısmını kaplayacak şekilde çoklu pencere modunda olsa bile cihaz ekranı için bir WindowMetrics
nesnesi döndürmek üzere WindowManager
getMaximumWindowMetrics()
platform yöntemini kullanın.
API düzeyi 14'e kadar olan uyumluluk için Jetpack WindowManager
kitaplığındaki WindowMetricsCalculator
computeMaximumWindowMetrics()
yöntemini kullanın.
Cihaz ekranının genişliğini ve yüksekliğini öğrenmek 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. Yakalanan içerik, medya projeksiyonu ayarlandığında elde edilen maksimum pencere metriklerinden farklı bir boyuttaysa medya projeksiyonu sinemaskoplu olabilir.
Medya projeksiyonunun, yakalanan herhangi bir bölge ve cihaz döndürmeleri için yakalanan içeriğin boyutuyla tam olarak uyumlu olmasını sağlamak amacıyla, 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
Aşağıdaki MediaProjection.Callback
API'leriyle uygulamanız medya projeksiyonu kullanıcı deneyimini özelleştirebilir:
onCapturedContentVisibilityChanged()
: Barındıran uygulamanın (medya projeksiyonunu başlatan uygulama) paylaşılan içeriği göstermesini veya gizlemesini sağlar.Yakalanan bölgenin kullanıcı tarafından görünür olup olmadığına bağlı olarak uygulamanızın kullanıcı arayüzünü özelleştirmek için bu geri çağırmayı kullanın. Örneğin, uygulamanız kullanıcı tarafından görülebiliyorsa ve yakalanan içeriği uygulamanın kullanıcı arayüzünde görüntülüyorsa ve yakalanan uygulama da kullanıcı tarafından görülebiliyorsa (bu geri çağırmada belirtildiği üzere) kullanıcı aynı içeriği iki kez görür. Yakalanan içeriği gizlemek ve uygulamanızda başka içerikler için düzen alanı açmak amacıyla geri çağırma işlevini kullanarak uygulamanızın kullanıcı arayüzünü güncelleyin.
onCapturedContentResize()
: Ana makine uygulamasının, yakalanan görüntüleme bölgesinin boyutuna göre sanal ekran ve medya projeksiyonuSurface
'ndaki medya projeksiyonunun boyutunu değiştirmesini sağlar.Yakalanan içerik (tek uygulama penceresi veya tam cihaz ekranı) boyut değiştirdiğinde tetiklenir (cihazın döndürülmesi veya yakalanan uygulamanın farklı bir aralık moduna girmesi nedeniyle). 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 için bu API'yi kullanın.
Kaynak kurtarma
Uygulamanız, uygulama tarafından tutulan sanal ekran ve projeksiyon yüzeyi gibi kaynakları serbest bırakmak için MediaProjection
onStop()
geri çağırmasını kaydetmelidir.
Medya projeksiyonu sona erdiğinde veya kullanıcı yakalama oturumuna devam etmek için izin vermediğinde geri çağırma çağrılır.
Uygulamanız geri çağırmayı kaydetmezse ve kullanıcı medya projeksiyonu oturumuna izin vermezse createVirtualDisplay()
, IllegalStateException
çağrısını gönderir.
Devre dışı bırak
Android 14 veya sonraki sürümlerde uygulama ekran paylaşımı varsayılan olarak etkindir. Her medya projeksiyonu oturumu, kullanıcılara bir uygulama penceresini veya ekranın tamamını paylaşma seçeneği sunar.
Uygulamanız, createScreenCaptureIntent(MediaProjectionConfig)
yöntemini createConfigForDefaultDisplay()
çağrısından döndürülen bir 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 ve MediaProjectionConfig
bağımsız değişkenine sahip createScreenCaptureIntent(MediaProjectionConfig)
çağrısı, varsayılan davranışla, yani createScreenCaptureIntent()
için yapılan çağrıyla aynıdır.
Yeniden boyutlandırılabilir uygulamalar
Medya projeksiyon uygulamalarınızı her zaman yeniden boyutlandırılabilir (resizeableActivity="true"
) yapın. Yeniden boyutlandırılabilir uygulamalar, cihaz yapılandırma değişikliklerini ve çoklu pencere modunu destekler (Çoklu pencere desteği bölümüne bakın).
Uygulamanız yeniden boyutlandırılabilir değilse bir pencere içeriğinden görüntüleme sınırlarını sorgulaması ve uygulama tarafından kullanılabilen maksimum görüntüleme alanının WindowMetrics
'ını almak için getMaximumWindowMetrics()
kullanması gerekir :
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();
Ek kaynaklar
Medya projeksiyonu hakkında daha fazla bilgi için Video kaydetme ve ses oynatma bölümüne bakın.