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 (API level 34) memperkenalkan berbagi layar aplikasi sehingga pengguna dapat membagikan satu jendela aplikasi, bukan seluruh layar perangkat, terlepas dari mode jendela. Berbagi layar aplikasi mengecualikan status bar, menu navigasi, 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 dibagikan.
Berbagi layar aplikasi memastikan privasi pengguna, meningkatkan produktivitas pengguna, dan meningkatkan multitasking dengan memungkinkan pengguna menjalankan beberapa aplikasi tetapi membatasi berbagi konten hanya untuk satu aplikasi.
Tiga representasi tampilan
Proyeksi media menangkap konten tampilan perangkat atau jendela aplikasi, lalu
memproyeksikan gambar yang diambil ke layar virtual yang merender gambar pada
Surface
.
Aplikasi ini menyediakan Surface
melalui
MediaRecorder
,
SurfaceTexture
, atau
ImageReader
, yang memakai
konten tampilan yang diambil 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 nyata
Mulai sesi proyeksi media dengan mendapatkan token yang memberi aplikasi Anda
kemampuan untuk merekam konten layar perangkat atau jendela aplikasi. Token
direpresentasikan 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
tangkapan 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]; 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 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.)
Platform
Menyesuaikan ukuran platform proyeksi media untuk menghasilkan output dalam resolusi yang sesuai. Buat permukaan menjadi besar (resolusi rendah) untuk transmisi layar ke TV atau monitor komputer, dan 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, mempertahankan rasio aspek, sehingga kedua dimensi konten (lebar dan tinggi) sama dengan atau kurang dari dimensi platform yang sesuai. Konten yang diambil kemudian dipusatkan ke permukaan.
Pendekatan penskalaan Android 12L meningkatkan transmisi layar ke televisi dan layar besar lainnya dengan memaksimalkan ukuran gambar platform sekaligus memastikan rasio aspek yang tepat.
Izin layanan latar depan
Jika aplikasi Anda menargetkan Android 14 atau yang lebih baru, 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 ini akan ditetapkan secara default
ke bilangan bulat bitwise dari jenis layanan latar depan 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 panggilan tunggal ke createVirtualDisplay()
. Token MediaProjection
hanya boleh digunakan sekali 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
Intent
yang ditampilkan daricreateScreenCaptureIntent()
kegetMediaProjection()
lebih dari sekali - Memanggil
createVirtualDisplay()
lebih dari sekali pada instanceMediaProjection
yang sama
Ukuran proyeksi media
Proyeksi media dapat merekam seluruh tampilan perangkat atau jendela aplikasi terlepas dari mode windowing.
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 diambil hingga pengguna memilih wilayah pengambilan gambar. 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 API level 14, gunakan metode computeMaximumWindowMetrics()
WindowMetricsCalculator
dari library Jetpack WindowManager
.
Panggil metode getBounds()
WindowMetrics
untuk mendapatkan lebar dan tinggi layar perangkat.
Perubahan ukuran
Ukuran proyeksi media dapat berubah saat perangkat diputar atau pengguna memilih jendela aplikasi sebagai region tangkapan di fitur berbagi layar aplikasi. Proyeksi media mungkin memiliki tampilan lebar jika konten yang direkam memiliki ukuran yang berbeda dari metrik jendela maksimum yang diperoleh saat proyeksi media disiapkan.
Untuk memastikan proyeksi media benar-benar sejajar dengan ukuran konten
yang diambil untuk setiap area yang diambil dan di seluruh rotasi perangkat, gunakan
callback onCapturedContentResize()
untuk mengubah ukuran pengambilan. (Untuk mengetahui informasi
selengkapnya, lihat bagian Penyesuaian, yang mengikuti).
Penyesuaian
Aplikasi Anda dapat menyesuaikan pengalaman pengguna proyeksi media dengan
MediaProjection.Callback
API berikut:
onCapturedContentVisibilityChanged()
: Mengaktifkan aplikasi host (aplikasi yang memulai proyeksi media) untuk menampilkan atau menyembunyikan konten yang dibagikan.Gunakan callback ini untuk menyesuaikan UI aplikasi Anda berdasarkan apakah wilayah yang diambil terlihat oleh pengguna atau tidak. Misalnya, jika aplikasi Anda dapat dilihat oleh pengguna dan menampilkan konten yang diambil dalam UI aplikasi, dan aplikasi yang diambil juga dapat dilihat 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 diambil dan mengosongkan ruang tata letak di aplikasi untuk konten lain.
onCapturedContentResize()
: Memungkinkan aplikasi host mengubah ukuran proyeksi media pada tampilan virtual dan proyeksi mediaSurface
berdasarkan ukuran area tampilan yang diambil.Dipicu setiap kali konten yang diambil—jendela aplikasi tunggal atau tampilan perangkat lengkap—mengubah ukuran (karena rotasi perangkat atau aplikasi yang direkam memasuki mode jendela yang berbeda). Gunakan API ini untuk mengubah ukuran tampilan dan platform virtual guna memastikan rasio aspek cocok dengan konten yang diambil dan tangkapan tidak ditampilkan dalam tampilan lebar.
Pemulihan resource
Aplikasi Anda harus mendaftarkan callback MediaProjection
onStop()
untuk merilis resource yang disimpan oleh aplikasi, seperti tampilan virtual dan
platform proyeksi.
Callback dipanggil saat proyeksi media berakhir atau saat pengguna tidak memberikan izin untuk melanjutkan sesi pengambilan gambar.
Jika aplikasi Anda tidak mendaftarkan callback dan pengguna tidak mengizinkan
sesi proyeksi media, panggilan ke createVirtualDisplay()
akan menampilkan
IllegalStateException
.
Nonaktifkan
Android 14 atau yang lebih baru mengaktifkan berbagi layar aplikasi secara default. Setiap sesi proyeksi media memberi pengguna opsi untuk membagikan jendela aplikasi atau seluruh tampilan.
Aplikasi Anda dapat memilih untuk tidak 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 dapat diubah ukurannya
Selalu buat aplikasi proyeksi media Anda dapat diubah ukurannya (resizeableActivity="true"
). Aplikasi
yang dapat diubah ukurannya mendukung perubahan konfigurasi perangkat dan mode multi-aplikasi (lihat
Dukungan multi-aplikasi).
Jika aplikasi Anda tidak dapat diubah ukurannya, aplikasi harus membuat kueri 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();
Referensi tambahan
Untuk informasi proyeksi media selengkapnya, lihat Merekam pemutaran video dan audio.