android.media.projection
API yang diperkenalkan di Android 5 (API level 21) memungkinkan Anda merekam konten
perangkat ditampilkan sebagai streaming media yang dapat Anda putar, rekam, atau transmisikan
perangkat lain, seperti TV.
Android 14 (level API 34) memperkenalkan berbagi layar aplikasi, yang memungkinkan pengguna berbagi satu jendela aplikasi, bukan seluruh layar perangkat, terlepas dari mode windowing. Berbagi layar aplikasi tidak mencakup {i>status bar<i}, {i>navigation bar<i}, notifikasi, dan elemen UI sistem lainnya dari tampilan bersama—bahkan saat berbagi layar aplikasi digunakan untuk merekam aplikasi dalam layar penuh. Hanya konten aplikasi yang dipilih yang akan dibagikan.
Berbagi layar aplikasi memastikan privasi pengguna, meningkatkan produktivitas pengguna, dan meningkatkan multitasking dengan memungkinkan pengguna menjalankan beberapa aplikasi, tetapi membatasi berbagi konten hanya dengan satu aplikasi.
Tiga representasi layar
Proyeksi media menangkap konten layar perangkat atau jendela aplikasi dan
kemudian memproyeksikan gambar yang diambil ke tampilan virtual yang merender gambar pada
Surface
.
![Tampilan perangkat sebenarnya yang diproyeksikan ke tampilan virtual. Konten
tampilan virtual yang ditulis ke `Surface` yang disediakan aplikasi.](https://developer.android.com/static/media/images/grow/media-projection.png?authuser=6&hl=id)
Surface
.
Aplikasi menyediakan Surface
melalui
MediaRecorder
SurfaceTexture
, atau
ImageReader
, yang menggunakan
konten tampilan yang diambil dan memungkinkan Anda mengelola gambar yang dirender
di Surface
secara real time. Anda dapat menyimpan gambar sebagai rekaman atau melakukan transmisi
mereka ke TV atau perangkat lain.
Tampilan nyata
Mulai sesi proyeksi media dengan mendapatkan token yang memberi aplikasi Anda
kemampuan untuk menangkap konten layar perangkat atau jendela aplikasi. Token
diwakili oleh sebuah instance
MediaProjection
.
Gunakan metode getMediaProjection()
Layanan sistem MediaProjectionManager
untuk membuat instance MediaProjection
saat memulai aktivitas baru. Mulai aktivitas dengan intent dari metode
Metode createScreenCaptureIntent()
untuk menentukan layar
operasi perekaman:
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());
Tampilan virtual
Inti proyeksi media adalah tampilan virtual, yang Anda buat
dengan memanggil
createVirtualDisplay()
pada instance MediaProjection
:
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);
Parameter width
dan height
menentukan dimensi virtual
tampilan. Untuk mendapatkan nilai lebar dan tinggi, gunakan metode
WindowMetrics
API diperkenalkan
di Android 11 (level API 30). (Untuk mengetahui detailnya, lihat
Ukuran proyeksi media.)
Platform
Menyesuaikan ukuran permukaan proyeksi media untuk menghasilkan output resolusi. Buat permukaan yang besar (resolusi rendah) untuk transmisi layar ke TV atau monitor komputer dan layar kecil (resolusi tinggi) untuk perekaman tampilan perangkat.
Mulai Android 12L (API level 32), saat merender konten yang diambil di platform, sistem akan menskalakan konten secara seragam, sehingga kedua dimensi konten (lebar dan tinggi) sama dengan atau kurang daripada dimensi permukaan yang sesuai. Konten yang direkam kemudian berpusat di permukaan.
Pendekatan penskalaan Android 12L meningkatkan transmisi layar ke televisi dan layar besar lainnya dengan memaksimalkan ukuran gambar permukaan sambil memastikan rasio aspek yang sesuai.
Izin layanan latar depan
Jika aplikasi Anda menargetkan Android 14 atau yang lebih tinggi, manifes aplikasi harus menyertakan
pernyataan izin untuk
Jenis layanan latar depan mediaProjection
:
<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>
Mulai layanan proyeksi media dengan panggilan ke startForeground()
.
Jika Anda tidak menentukan jenis layanan latar depan dalam panggilan, jenis layanan tersebut akan
ke integer bitwise dari jenis layanan latar depan yang ditentukan dalam manifes. Jika
manifes tidak menentukan tipe layanan apa pun, sistem akan menampilkan
MissingForegroundServiceTypeException
.
Izin pengguna
Aplikasi Anda harus meminta izin pengguna sebelum setiap sesi proyeksi media. J
sesi adalah panggilan tunggal ke createVirtualDisplay()
. Token MediaProjection
hanya boleh digunakan sekali untuk melakukan panggilan.
Di Android 14 atau yang lebih baru, metode createVirtualDisplay()
akan menampilkan
SecurityException
jika
aplikasi melakukan salah satu hal berikut:
- Meneruskan instance
Intent
yang ditampilkan daricreateScreenCaptureIntent()
kegetMediaProjection()
lebih dari sekali - Menelepon
createVirtualDisplay()
lebih dari sekali diMediaProjection
yang sama {i>instance<i}
Ukuran proyeksi media
Proyeksi media dapat merekam keseluruhan tampilan perangkat atau jendela aplikasi terlepas dari mode windowing.
Ukuran awal
Dengan proyeksi media layar penuh, aplikasi Anda harus menentukan ukuran layar perangkat. Dalam berbagi layar aplikasi, aplikasi Anda tidak akan dapat menentukan ukuran tampilan yang diambil hingga pengguna memilih region penangkapan. Jadi, ukuran awal dari setiap proyeksi media adalah ukuran layar perangkat.
Gunakan platform WindowManager
Metode getMaximumWindowMetrics()
untuk menampilkan
Objek WindowMetrics
untuk
layar perangkat meskipun aplikasi host proyeksi media berada dalam multi-aplikasi
yang hanya memenuhi sebagian layar.
Untuk kompatibilitas hingga level API 14, gunakan WindowMetricsCalculator
computeMaximumWindowMetrics()
dari library Jetpack WindowManager
.
Panggil metode WindowMetrics
getBounds()
untuk mendapatkan lebar dan tinggi layar perangkat.
Perubahan ukuran
Ukuran proyeksi media dapat berubah saat perangkat diputar atau pengguna memilih jendela aplikasi sebagai region pengambilan dalam berbagi layar aplikasi. Proyeksi media mungkin akan dijadikan tampilan lebar jika konten yang diambil adalah berbeda dari metrik jendela maksimum yang diperoleh saat media proyeksi telah diatur.
Untuk memastikan proyeksi media sejajar dengan ukuran gambar yang
untuk setiap wilayah yang direkam dan di seluruh rotasi perangkat, gunakan
Callback onCapturedContentResize()
untuk mengubah ukuran rekaman. (Untuk selengkapnya
informasi tambahan, lihat bagian Penyesuaian, yang mengikuti).
Penyesuaian
Aplikasi Anda dapat menyesuaikan pengalaman pengguna proyeksi media dengan hal berikut
MediaProjection.Callback
API:
onCapturedContentVisibilityChanged()
: Memungkinkan aplikasi host (aplikasi yang memulai proyeksi media) menampilkan atau menyembunyikan konten yang dibagikan.Gunakan callback ini untuk menyesuaikan UI aplikasi Anda berdasarkan apakah region dapat dilihat oleh pengguna. Misalnya, jika aplikasi Anda dapat dilihat oleh pengguna dan menampilkan konten yang direkam dalam UI aplikasi, dan aplikasi yang direkam juga dapat dilihat oleh pengguna (seperti yang ditunjukkan melalui callback), pengguna akan melihat konten yang sama dua kali. Menggunakan callback untuk memperbarui UI aplikasi Anda untuk menyembunyikan konten yang diambil dan mengosongkan ruang tata letak di aplikasi untuk konten lainnya.
onCapturedContentResize()
: Memungkinkan aplikasi host mengubah ukuran proyeksi media pada virtual proyeksi media dan tampilanSurface
berdasarkan ukuran kamera yang region tampilan.Dipicu setiap kali konten yang diambil—satu jendela aplikasi atau penuh tampilan perangkat—mengubah ukuran (karena rotasi perangkat atau gambar aplikasi memasuki mode windowing yang berbeda). Gunakan API ini untuk mengubah ukuran tampilan dan platform virtual untuk memastikan rasio aspek cocok dengan yang diambil konten dan rekaman tidak dijadikan tampilan lebar.
Pemulihan resource
Aplikasi Anda harus mendaftarkan MediaProjection
onStop()
untuk diberi tahu saat sesi proyeksi media dihentikan dan menjadi
tidak valid. Saat sesi dihentikan, aplikasi Anda harus melepaskan resource yang
yang digunakannya, seperti tampilan
virtual dan permukaan proyeksi. A dihentikan
sesi proyeksi media tidak lagi dapat
membuat tampilan virtual baru, meskipun
aplikasi Anda belum pernah membuat tampilan virtual untuk proyeksi media tersebut.
Callback dipanggil saat proyeksi media dihentikan, baik karena menghentikan sesi secara manual, atau karena sistem menghentikan sesi untuk suatu alasan.
Jika aplikasi Anda tidak mendaftarkan callback, panggilan apa pun ke createVirtualDisplay()
lemparan
IllegalStateException
.
Nonaktifkan
Android 14 atau yang lebih baru mengaktifkan berbagi layar aplikasi secara default. Setiap media sesi proyeksi memberi pengguna opsi untuk berbagi jendela aplikasi atau seluruh tampilan.
Aplikasi Anda dapat memilih untuk tidak ikut serta dalam berbagi layar aplikasi dengan memanggil
Metode createScreenCaptureIntent(MediaProjectionConfig)
dengan argumen MediaProjectionConfig
yang ditampilkan dari panggilan ke
createConfigForDefaultDisplay()
.
Panggilan ke createScreenCaptureIntent(MediaProjectionConfig)
dengan
Argumen MediaProjectionConfig
ditampilkan dari panggilan ke
createConfigForUserChoice()
sama
sebagai perilaku {i>default<i}, yaitu panggilan ke
createScreenCaptureIntent()
Aplikasi yang dapat diubah ukurannya
Selalu buat aplikasi proyeksi media Anda dapat diubah ukurannya (resizeableActivity="true"
). Dapat diubah ukurannya
aplikasi mendukung perubahan konfigurasi perangkat dan mode multi-aplikasi (lihat
Dukungan multi-aplikasi).
Jika aplikasi Anda tidak dapat diubah ukurannya, aplikasi harus mengkueri batas tampilan dari jendela
konteks dan gunakan getMaximumWindowMetrics()
untuk mengambil WindowMetrics
area tampilan maksimum yang tersedia untuk aplikasi :
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();
Referensi lainnya
Untuk informasi proyeksi media selengkapnya, lihat Merekam pemutaran video dan audio.