Medya tahmini

Android 5'te (API düzeyi 21) kullanıma sunulan medya projeksiyon API'leri, bir 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ızı sağlar.

Bir medya projeksiyonu cihaz ekranının üç temsilini içerir:

Sanal ekrana yansıtılan gerçek cihaz ekranı. Uygulama tarafından sağlanan "Surface"e yazılan sanal görüntülü reklam içeriği.
Şekil 1. Sanal ekrana yansıtılan gerçek cihaz ekranı. Uygulama tarafından sağlanan Surface öğesine yazılan sanal görüntülü reklam içeriği.

Medya projeksiyonu, bir cihaz ekranının içeriğini yakalar ve ardından yakalanan görüntüyü, görüntüyü Surface üzerinde oluşturan sanal bir ekrana yansıtır.

Uygulama, Surface özelliğini, yakalanan ekranın içeriğini kullanan bir SurfaceView veya ImageReader aracılığıyla sağlar. ImageReader öğesinin OnImageAvailableListener sayesinde Surface üzerinde oluşturulan görüntüleri gerçek zamanlı olarak yönetebilirsiniz. Görüntüleri kayıt olarak kaydedebilir veya TV'ye ya da başka bir cihaza yayınlayabilirsiniz.

MedyaProjeksiyonu

Uygulamaya ekran içeriklerini, cihaz sesini ya da her ikisini 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 bu sınıfın bir örneğini oluşturabilirsiniz.

Eski yaklaşım

Eski yaklaşımı kullanarak medya projeksiyon jetonu almak için MediaProjectionManager sistem hizmetinin createScreenCaptureIntent() yönteminden döndürülen bir niyetle startActivityForResult() yöntemini çağırın:

Kotlin

startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(),
                       REQUEST_MEDIA_PROJECTION)

Java

startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(),
                       REQUEST_MEDIA_PROJECTION);

Çağrı, kullanıcıya medya projeksiyonunun, hassas veya kimliği tanımlayabilecek bilgiler dahil olmak üzere görüntülenen tüm bilgileri yakaladığını bildiren bir onay iletişim kutusu görüntüler.

Kullanıcı onay verirse startActivityForResult(), onActivityResult() geri çağırmasına bir sonuç kodu ve veri aktarır.

Daha sonra, MediaProjection örneği oluşturmak için verileri ve sonuç kodunu MediaProjectionManager kaynağından getMediaProjection() yöntemine aktarabilirsiniz:

Kotlin

mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, resultData)

Java

mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, resultData);

Medya projeksiyon jetonu almak için önerilen yaklaşım, Jetpack Activity kitaplığındaki API'leri kullanır:

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 genişliğini ve yüksekliğini belirtir. Medya projeksiyonunun genişliği ve yüksekliğiyle eşleşen değerler elde etmek için Android 11'de (API düzeyi 30) kullanıma sunulan WindowMetrics API'lerini kullanın.

Pencere Metrikleri

Medya projeksiyonu, medya projeksiyonunu oluşturan uygulamanın tam ekran veya çoklu pencere modunda çalışmasına bakılmaksızın ekranın tamamını yakalar.

Bir medya projeksiyonunun boyutlarını almak için medya projeksiyonu uygulaması, ekranın yalnızca bir kısmını kaplayacak şekilde çoklu pencere modunda olsa bile tam ekran için bir WindowMetrics nesnesi döndüren WindowManager#getMaximumWindowMetrics() aracını kullanın.

API düzeyi 14'e kadar olan uyumluluk için Jetpack WindowManager kitaplığındaki WindowMetricsCalculator#computeMaximumWindowMetrics() aracını kullanın.

Medya projeksiyonunun sanal ekranı için doğru genişliği ve yüksekliği almak üzere WindowMetrics#getBounds() yöntemini çağırın (bkz. Sanal görüntüleme).

Medya yansıtma uygulamalarınızı her zaman yeniden boyutlandırılabilir yapın. 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ılabilir değilse bir pencere içeriğinden görüntüleme sınırlarını sorgulaması ve WindowManager#getMaximumWindowMetrics() kullanarak uygulamanın kullanabileceği maksimum görüntüleme alanının WindowMetrics kadarını alması 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();

Yüzey

Medya projeksiyon yüzeyini istediğiniz çözünürlükte çıktı üretecek şekilde boyutlandırmanız gerekir. TV'lere veya bilgisayar monitörlerine ekran yayını için boyutu büyük (düşük çözünürlük), cihaz ekranı kaydı için ise küçük (yüksek çözünürlüklü) yapın.

12L'den (API düzeyi 32) itibaren, sistem yüzeyde sanal bir ekran oluşturduğunda ImageView'deki centerInside seçeneğine benzer bir işlemi kullanarak sanal ekranı yüzeye sığacak şekilde ölçeklendirir.

Yeni ö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.

Öneriler

Medya projeksiyonu ile en iyi sonuçları elde etmek için aşağıdaki önerileri uygulayın:

  • Uygulamanızı yeniden boyutlandırılabilir hale getirin. 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). Uygulama manifestinizde resizeableActivity="true" değerini ayarlayın. Android 7.0 (API düzeyi 24) ve sonraki sürümlerde bu ayar varsayılan olarak doğrudur.
  • Telefon, tablet ve katlanabilir form faktörlerinde her iki yön de ortak olduğundan, uygulamalarınızın yatay ve dikey yönleri desteklemesini sağlayın.
  • Medya projeksiyonunun sınırlarını öğrenmek için WindowManager#getMaximumWindowMetrics() kullanın. API düzeyi 14'e kadar olan uyumluluk için Jetpack WindowManager'ı kullanın. (WindowMetrics bölümünü inceleyin.)
  • Uygulamanız yeniden boyutlandırılabilir değilse bir pencere içeriğinden medya projeksiyonu sınırlarını alın. (Pencere Metrikleri bölümüne bakın.)

Ek kaynaklar

Medya projeksiyonu hakkında daha fazla bilgi için Video kaydetme ve ses oynatma bölümüne bakın.