android.media.projection API yang diperkenalkan di Android 5 (level API 21)
memungkinkan Anda merekam konten layar perangkat sebagai streaming media yang
dapat diputar, direkam, atau ditransmisikan ke perangkat lain seperti TV.
Android 14 (level API 34) memperkenalkan fitur berbagi layar aplikasi, yang memungkinkan pengguna berbagi satu jendela aplikasi, bukan seluruh layar perangkat, terlepas dari mode jendela. Fitur berbagi layar aplikasi mengecualikan status bar, menu navigasi, notifikasi, dan elemen UI sistem lainnya dari layar yang dibagikan—bahkan saat fitur berbagi layar aplikasi digunakan untuk merekam aplikasi dalam layar penuh. Hanya konten aplikasi yang dipilih yang dibagikan.
Fitur berbagi layar aplikasi memastikan privasi pengguna, meningkatkan produktivitas pengguna, dan meningkatkan multitasking dengan memungkinkan pengguna menjalankan beberapa aplikasi, tetapi membatasi berbagi konten hanya ke satu aplikasi.
Tiga representasi tampilan
Proyeksi media merekam konten layar perangkat atau jendela aplikasi, lalu memproyeksikan gambar yang direkam ke tampilan virtual yang merender gambar pada
a Surface.
Surface yang disediakan aplikasi.
Aplikasi menyediakan Surface melalui MediaRecorder,
SurfaceTexture, atau ImageReader, yang menggunakan konten tampilan yang
direkam dan memungkinkan Anda mengelola gambar yang dirender di Surface secara
real time. Anda dapat menyimpan gambar sebagai rekaman atau mentransmisikannya ke TV atau perangkat lainnya.
Tampilan sebenarnya
Mulai sesi proyeksi media dengan mendapatkan token yang memberi aplikasi Anda kemampuan untuk merekam konten layar perangkat atau jendela aplikasi. Token
tersebut diwakili oleh instance class MediaProjection.
Gunakan metode getMediaProjection() dari layanan sistem MediaProjectionManager
untuk membuat instance MediaProjection saat Anda memulai aktivitas baru. Mulai aktivitas dengan intent dari metode
createScreenCaptureIntent() untuk menentukan operasi perekaman layar:
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];
ActivityResultLauncherstartMediaProjection = 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 tampilan virtual. Untuk mendapatkan nilai lebar dan tinggi, gunakan WindowMetrics API
yang diperkenalkan di Android 11 (level API 30). (Untuk mengetahui detailnya, lihat bagian Ukuran proyeksi
media.)
Permukaan
Tentukan ukuran platform proyeksi media untuk menghasilkan output dalam resolusi yang sesuai. Buat platform besar (resolusi rendah) untuk transmisi layar ke TV atau monitor komputer dan platform kecil (resolusi tinggi) untuk perekaman layar perangkat.
Mulai Android 12L (level API 32), saat merender konten yang direkam di platform, sistem akan menskalakan konten secara seragam, mempertahankan rasio aspek, sehingga kedua dimensi konten (lebar dan tinggi) sama dengan atau kurang dari dimensi platform yang sesuai. Konten yang direkam kemudian dipusatkan pada platform.
Pendekatan penskalaan Android 12L mengoptimalkan transmisi layar ke televisi dan layar besar lainnya dengan memaksimalkan ukuran gambar platform sekaligus memastikan rasio aspek yang tepat.
Izin layanan foreground
Jika aplikasi Anda menargetkan Android 14 atau yang lebih tinggi, manifes aplikasi harus menyertakan a
deklarasi izin untuk jenis layanan mediaProjection
foreground:
<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 foreground dalam panggilan, jenis tersebut akan ditetapkan secara default ke bilangan bulat bitwise dari jenis layanan foreground yang ditentukan dalam manifes. Jika
manifes tidak menentukan jenis layanan apa pun, sistem akan menampilkan
MissingForegroundServiceTypeException.
Izin pengguna
Aplikasi Anda harus meminta izin pengguna sebelum setiap sesi proyeksi media. Sesi adalah satu panggilan ke createVirtualDisplay(). Token MediaProjection hanya boleh digunakan satu kali untuk melakukan panggilan.
Di Android 14 atau yang lebih tinggi, metode createVirtualDisplay() akan menampilkan
SecurityException jika aplikasi Anda melakukan salah satu hal berikut:
- Meneruskan instance
Intentyang ditampilkan daricreateScreenCaptureIntent()kegetMediaProjection()lebih dari satu kali - Memanggil
createVirtualDisplay()lebih dari satu kali pada instanceMediaProjectionyang sama
Ukuran proyeksi media
Proyeksi media dapat merekam seluruh layar perangkat atau jendela aplikasi, terlepas dari mode jendela.
Ukuran awal
Dengan proyeksi media layar penuh, aplikasi Anda harus menentukan ukuran layar perangkat. Dalam fitur berbagi layar aplikasi, aplikasi Anda tidak akan dapat menentukan ukuran layar yang direkam hingga pengguna memilih area perekaman. Jadi, ukuran awal proyeksi media apa pun adalah ukuran layar perangkat.
Gunakan metode WindowManager getMaximumWindowMetrics() platform untuk
menampilkan objek WindowMetrics untuk layar perangkat meskipun aplikasi host
proyeksi media berada dalam mode multi-aplikasi, yang hanya menempati sebagian
layar.
Untuk kompatibilitas hingga level API 14, gunakan metode WindowMetricsCalculator
computeMaximumWindowMetrics() dari library WindowManager
Jetpack.
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 area perekaman dalam fitur berbagi layar aplikasi. Proyeksi media mungkin memiliki kotak surat jika konten yang direkam memiliki ukuran yang berbeda dengan metrik jendela maksimum yang diperoleh saat proyeksi media disiapkan.
Untuk memastikan proyeksi media selaras dengan ukuran konten yang direkam untuk setiap area yang direkam dan di seluruh rotasi perangkat, gunakan callback onCapturedContentResize() untuk mengubah ukuran perekaman. (Untuk mengetahui informasi selengkapnya, lihat bagian Penyesuaian, yang mengikuti).
Penyesuaian
Aplikasi Anda dapat menyesuaikan pengalaman pengguna proyeksi media dengan
MediaProjection.Callback API berikut:
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 area yang direkam terlihat oleh pengguna. Misalnya, jika aplikasi Anda terlihat oleh pengguna dan menampilkan konten yang direkam dalam UI aplikasi, dan aplikasi yang direkam juga terlihat oleh pengguna (seperti yang ditunjukkan melalui callback ini), pengguna akan melihat konten yang sama dua kali. Gunakan callback untuk mengupdate UI aplikasi Anda guna menyembunyikan konten yang direkam dan mengosongkan ruang tata letak di aplikasi Anda untuk konten lainnya.
onCapturedContentResize(): Memungkinkan aplikasi host mengubah ukuran proyeksi media pada tampilan virtual danSurfaceproyeksi media berdasarkan ukuran area layar yang direkam.Dipicu setiap kali konten yang direkam—satu jendela aplikasi atau layar perangkat penuh—berubah ukuran (karena rotasi perangkat atau aplikasi yang direkam memasuki mode jendela yang berbeda). Gunakan API ini untuk mengubah ukuran tampilan virtual dan platform guna memastikan rasio aspek cocok dengan konten yang direkam dan perekaman tidak memiliki kotak surat.
Pemulihan resource
Aplikasi Anda harus mendaftarkan callback MediaProjection onStop() agar diberi tahu saat sesi proyeksi media dihentikan dan menjadi tidak valid. Saat sesi dihentikan, aplikasi Anda harus melepaskan resource yang dimilikinya, seperti tampilan virtual dan platform proyeksi. Sesi proyeksi media yang dihentikan tidak dapat lagi membuat tampilan virtual baru, meskipun aplikasi Anda belum pernah membuat tampilan virtual untuk proyeksi media tersebut.
Sistem memanggil callback saat proyeksi media dihentikan. Penghentian ini dapat terjadi karena beberapa alasan, seperti:
- pengguna menghentikan sesi menggunakan UI aplikasi atau chip status bar proyeksi media sistem
- layar sedang dikunci
- sesi proyeksi media lain dimulai
- proses aplikasi dihentikan
Jika aplikasi Anda tidak mendaftarkan callback, setiap panggilan ke createVirtualDisplay()
akan menampilkan IllegalStateException.
Nonaktifkan
Android 14 atau yang lebih tinggi mengaktifkan fitur berbagi layar aplikasi secara default. Setiap sesi proyeksi media memberi pengguna opsi untuk berbagi jendela aplikasi atau seluruh layar.
Aplikasi Anda dapat menonaktifkan fitur berbagi layar aplikasi dengan memanggil metode
createScreenCaptureIntent(MediaProjectionConfig) dengan argumen
MediaProjectionConfig yang ditampilkan dari panggilan ke
createConfigForDefaultDisplay().
Panggilan ke createScreenCaptureIntent(MediaProjectionConfig) dengan argumen
MediaProjectionConfig yang ditampilkan dari panggilan ke
createConfigForUserChoice() sama dengan perilaku default, yaitu
panggilan ke createScreenCaptureIntent().
Aplikasi yang ukurannya dapat disesuaikan
Selalu buat aplikasi proyeksi media Anda dapat diubah ukurannya
(resizeableActivity="true"). Aplikasi yang ukurannya dapat disesuaikan mendukung perubahan konfigurasi perangkat
dan mode multi-aplikasi (lihat Dukungan multi-aplikasi).
Jika aplikasi tidak dapat diubah ukurannya, aplikasi harus mengkueri batas tampilan dari konteks jendela dan menggunakan 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();
Chip status bar dan penghentian otomatis
Eksploitasi proyeksi layar mengekspos data pengguna pribadi seperti informasi keuangan karena pengguna tidak menyadari bahwa layar perangkat mereka sedang dibagikan.
Untuk aplikasi yang berjalan di perangkat dengan Android 15 QPR1 atau yang lebih baru, chip status bar yang besar dan jelas akan memberi tahu pengguna tentang proyeksi layar yang sedang berlangsung. Pengguna dapat mengetuk chip untuk menghentikan layar mereka agar tidak dibagikan, ditayangkan, atau direkam. Selain itu, proyeksi layar akan otomatis berhenti saat layar perangkat dikunci.
Uji ketersediaan chip status bar proyeksi media dengan memulai berbagi layar, transmisi, atau perekaman. Chip akan muncul di status bar.
Untuk memastikan aplikasi Anda melepaskan resource dan mengupdate UI-nya saat proyeksi layar dihentikan oleh interaksi pengguna dengan chip status bar atau dengan aktivasi layar kunci, lakukan hal berikut:
Buat instance
MediaProjection.Callback.Implementasikan metode callback
onStop(). Metode ini dipanggil saat proyeksi layar berhenti. Lepaskan resource apa pun yang dimiliki aplikasi Anda dan update UI aplikasi sesuai kebutuhan.
Untuk menguji callback, ketuk chip status bar atau kunci layar perangkat untuk menghentikan proyeksi layar. Pastikan metode onStop() dipanggil dan aplikasi Anda merespons seperti yang diharapkan.
Referensi lainnya
Untuk informasi proyeksi media selengkapnya, lihat Merekam pemutaran video dan audio.