Medya projeksiyonu

android.media.projection Android 5'te (API düzeyi 21) kullanıma sunulan API'ler, içerikleri yakalamanıza olanak tanır. içeriği oynatabileceğiniz, kaydedebileceğiniz veya yayınlayabileceğiniz bir medya akışı olarak TV'ler gibi diğer cihazlar.

Android 14'te (API düzeyi 34), kullanıcıların şu işlemleri yapmasına olanak tanıyan uygulama ekran paylaşımı özelliği kullanıma sunuldu: ne olursa olsun cihaz ekranının tamamı yerine tek bir uygulama penceresini pencere modu. Uygulama ekran paylaşımı; durum çubuğu, gezinme çubuğu, ve paylaşılan ekrandaki diğer sistem kullanıcı arayüzü öğeleri dahil, Uygulama ekran paylaşımı bir uygulamayı tam ekranda yakalamak için kullanıldığında. Yalnızca seçilen uygulamanın içeriği 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 uygulama çalıştırmasına olanak tanır ancak birden fazla işi aynı anda yapma tek bir uygulamayla paylaşabiliyor.

Üç ekran temsili

Medya projeksiyonu, bir cihaz ekranının veya uygulama penceresinin içeriğini yakalar ve sonra yakalanan görüntüyü, görüntünün her bir sayfasını oluşturan sanal ekrana yansıtır Surface.

Gerçek cihaz ekranı, sanal ekrana yansıtılır. İçindekiler
              uygulama tarafından sağlanan "Yüzey"e yazılan sanal ekran.
Şekil 1. Gerçek cihaz ekranı veya uygulama penceresi üzerine yansıtılan sanal ekrandır. Uygulama tarafından sağlanana yazılan sanal ekran Surface

Uygulama, Surface özelliğini bir MediaRecorder SurfaceTexture veya ImageReader, yakalanan ekranın içeriğini belirtir ve oluşturulan resimleri yönetmenize olanak tanır. Surface üzerinde gerçek zamanlı olarak. Görüntüleri kayıt veya yayınlama olarak saklayabilirsiniz TV'ye veya başka bir cihaza gönderebiliyorlar.

Gerçek görüntülü reklam

Uygulamanıza şunu sağlayan bir jeton alarak medya projeksiyonu oturumu başlatın: cihaz ekranının veya uygulama penceresinin içeriğini yakalama imkanı. Jeton bir örneği ile temsil edilir MediaProjection sınıfını kullanır.

Şu öğenin getMediaProjection() yöntemini kullanın: MediaProjection örneği oluşturmak için MediaProjectionManager sistem hizmeti yeni bir aktivite başlatın. Etkinliği, CANNOT TRANSLATE Ekran belirtmek için createScreenCaptureIntent() yöntemi yakalama işlemi:

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 merkezinde, oluşturduğunuz sanal ekran telefonla arayarak createVirtualDisplay() MediaProjection örneğinde:

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 makinelerin görüntüleyin. Genişlik ve yükseklik değerlerini almak için, WindowMetrics API kullanıma sunuldu . (Ayrıntılar için Medya projeksiyon boyutu bölümü).

Platform

Medya projeksiyon yüzeyini uygun biçimde çıktı üretecek şekilde boyutlandırın belirler. TV'lere ekran yayını yapmak için yüzeyi büyük (düşük çözünürlük) yapın veya bilgisayar monitörleri ve cihaz ekran kaydı için küçük (yüksek çözünürlük) kullanabilirsiniz.

Android 12L (API düzeyi 32) sürümünden itibaren, sistem, en boy oranını koruyarak içeriği eşit şekilde ölçeklendirir ve içeriğin her iki boyutunun da (genişlik ve yükseklik) eşit veya daha küçük olacağı şekilde daha büyük bir değer elde edersiniz. Yakalanan içerik bir araya getirmektir.

Android 12L ölçeklendirme yaklaşımı, televizyonlarda ekran yayınlamayı iyileştirir. yüzey görüntüsünün boyutunu en üst düzeye çıkararak diğer büyük ekranlarda da uygun en boy oranı.

Ön plan hizmeti izni

Uygulamanız Android 14 veya sonraki bir sürümü hedefliyorsa uygulama manifesti şunları içermelidir: için izin beyanı mediaProjection ön plan hizmet tü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() çağrısı yaparak medya projeksiyon hizmetini başlatın.

Görüşmede ön plan hizmeti türünü belirtmezseniz tür varsayılan olarak ayarlanır manifest dosyasında tanımlanan ön plan hizmeti türlerinin bit tabanlı bir tamsayısına dönüştürün. Eğer manifesto herhangi bir hizmet türü belirtmiyorsa, sistem MissingForegroundServiceTypeException.

Uygulamanız her medya projeksiyon oturumundan önce kullanıcı izni istemelidir. CEVAP oturum, createVirtualDisplay() için yapılan tek bir aramadır. MediaProjection jetonu arama yapmak için yalnızca bir kez kullanılmalıdır.

Android 14 veya sonraki sürümlerde createVirtualDisplay() yöntemi Şu durumda SecurityException: uygulaması aşağıdakilerden birini yapar:

  • createScreenCaptureIntent() öğesinden getMediaProjection() öğesine birden fazla kez döndürülen Intent örneğini geçirir
  • createVirtualDisplay() için aynı MediaProjection üzerinde birden fazla kez arama örnek

Medya projeksiyonu boyutu

Medya projeksiyonu, cihaz ekranının tamamını veya bir uygulama penceresini yakalayabilir pencere modundan bağımsız olarak değiştirebilirsiniz.

Başlangıç boyutu

Tam ekran medya projeksiyonu ile, uygulamanız cihaz ekranına gidin. Uygulamanız, uygulama ekran paylaşımında yakalama bölgesi seçene kadar yakalanan ekranın boyutunu değiştirebilir. Yani bir medya projeksiyonunun başlangıç boyutu, cihaz ekranının boyutudur.

WindowManager platformunu kullan getMaximumWindowMetrics() yöntemi için WindowMetrics nesnesi medya projeksiyonu ana makine uygulaması çoklu pencerede olsa bile cihaz ekranı kullanarak ekranın yalnızca bir kısmını kaplar.

API düzeyi 14'e kadar uyumluluk için WindowMetricsCalculator computeMaximumWindowMetrics() kullanın. yöntemini Jetpack WindowManager kitaplığından alabilirsiniz.

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

Medya projeksiyonunun boyutu, cihaz döndürüldüğünde değişebilir veya kullanıcı, uygulama ekran paylaşımında yakalama bölgesi olarak bir uygulama penceresini seçer. Yakalanan içerik boyutu, medya öğeleri eklendiğinde elde edilen maksimum aralık metriklerinden projeksiyonu oluşturulmaya çalışıldı.

Medya projeksiyonunun yakalanan görüntünün boyutuyla tam olarak uyumlu olmasını sağlamak için farklı cihaz rotasyonları için içerik kullanıyorsanız Yakalamayı yeniden boyutlandırmak için onCapturedContentResize() geri çağırması yapın. (Daha fazla bilgi için, aşağıda yer alan Özelleştirme bölümüne bakın).

Özelleştirme

Uygulamanız, medya projeksiyonu kullanıcı deneyimini aşağıdakileri kullanarak özelleştirebilir MediaProjection.Callback API'ler:

  • onCapturedContentVisibilityChanged(): Ana makine uygulamasının (medya projeksiyonunu başlatan uygulama) gösterilmesini veya Paylaşılan içeriği gizleyebilirsiniz.

    Yakalanan görüntülerin bölgenin kullanıcıya görünür olduğunu gösterir. Örneğin, uygulamanız yakalanan içeriği uygulamanın kullanıcı arayüzünde göstermesi ve kullanıcı tarafından da görülebilir (bu bağlantıda belirtildiği şekilde geri çağırma) kullanıldığında, kullanıcı aynı içeriği iki kez görür. Güncellemek için geri çağırmayı kullanın yakalanan içeriği gizlemek ve uygulamama ekleyebilirsiniz.

  • onCapturedContentResize(): Ana makine uygulamasının, sanal makinedeki medya projeksiyonunun boyutunu değiştirmesine izin verir. yakalanan videonun boyutuna göre görüntülü reklam ve medya projeksiyonu Surface görüntüleme bölgesi.

    Yakalanan içerik (tek bir uygulama penceresi veya tamamı) olduğunda tetiklenir cihaz ekranı - boyut değişir (cihazın döndürülmesi veya yakalanan başka bir pencere moduna giren uygulama) girin. Hem en boy oranının, çekilen resimle eşleştiğinden emin olmak için sanal ekran ve yüzey ve yakalama sinemaskoplu olmamalıdır.

Kaynak kurtarma

Uygulamanız MediaProjection onStop() medya projeksiyonu oturumu durdurulduğunda bilgilendirilmek üzere geri çağırma geçersiz. Oturum durdurulduğunda, uygulamanız istenen kaynakları sanal ekran ve projeksiyon yüzeyi gibi öğeler içerir. A durduruldu medya projeksiyon oturumu artık yeni bir sanal ekran oluşturamıyor. Uygulamanız bu medya projeksiyonu için daha önce sanal ekran oluşturmadıysa.

Geri çağırma, medya projeksiyonu sona erdiğinde çağrılır; çünkü veya sistem, oturumu manuel olarak durdurduğunda bir neden olabilir.

Uygulamanız geri çağırmayı kaydetmiyorsa createVirtualDisplay() için yapılan herhangi bir çağrı atar IllegalStateException.

Devre dışı bırak

Android 14 veya sonraki sürümlerde uygulama ekran paylaşımı varsayılan olarak etkinleştirilir. Her bir medya projeksiyon oturumunda, kullanıcılara bir uygulama penceresini paylaşma seçeneği sunulur. ekranın tamamını görüntüleyebilir.

Uygulamanız, createScreenCaptureIntent(MediaProjectionConfig) yöntem şuna yapılan bir çağrıdan döndürülen MediaProjectionConfig bağımsız değişkeniyle: createConfigForDefaultDisplay().

createScreenCaptureIntent(MediaProjectionConfig) için bir çağrı Şuna yapılan çağrıdan MediaProjectionConfig bağımsız değişken döndürüldü: createConfigForUserChoice() aynı bu varsayılan davranış olarak, yani createScreenCaptureIntent().

Yeniden boyutlandırılabilen uygulamalar

Medya projeksiyon uygulamalarınızı her zaman yeniden boyutlandırılabilir yapın (resizeableActivity="true"). Yeniden boyutlandırılabilir cihaz yapılandırma değişikliklerini ve çoklu pencere modunu destekler (bkz. Çoklu pencere desteği).

Uygulamanız yeniden boyutlandırılamıyorsa görüntüleme sınırlarını bir pencereden sorgulamalıdır bağlamını ve WindowMetrics öğesini almak için getMaximumWindowMetrics() uygulama tarafından kullanılabilen maksimum görüntüleme alanı :

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 bkz. Video ve ses oynatmayı kaydedin.