API chiếu nội dung nghe nhìn được giới thiệu trong phiên bản Android 5 (API cấp 21) cho phép bạn chụp lại nội dung của màn hình thiết bị dưới dạng luồng nội dung nghe nhìn bạn có thể phát lại, quay hoặc truyền sang các thiết bị khác như TV.
Quá trình chiếu nội dung nghe nhìn bao gồm ba cách biểu thị của màn hình thiết bị:

Surface
do ứng dụng cung cấp.
Tính năng chiếu nội dung nghe nhìn sẽ chụp lại nội dung của màn hình thiết bị, sau đó chiếu hình ảnh được chụp lên màn hình ảo để kết xuất hình ảnh đó trên
Surface
.
Ứng dụng này cung cấp Surface
thông qua
SurfaceView
hoặc
ImageReader
, một trong hai sẽ sử dụng nội dung của màn hình được chụp.
OnImageAvailableListener
của ImageReader
cho phép bạn quản lý hình ảnh được kết xuất trên Surface
theo thời gian thực. Bạn có thể lưu hình ảnh dưới dạng bản ghi hoặc truyền vào TV hoặc thiết bị khác.
MediaProjection
Bắt đầu phiên chiếu nội dung nghe nhìn bằng cách lấy mã thông báo giúp ứng dụng có thể chụp lại nội dung hiển thị, âm thanh thiết bị hoặc cả hai. Mã thông báo này được biểu thị bằng một thực thể của lớp
MediaProjection
. Bạn có thể tạo một thực thể của lớp này khi bắt đầu một hoạt động mới.
Phương pháp cũ
Để có được mã thông báo chiếu nội dung nghe nhìn bằng phương pháp cũ, hãy gọistartActivityForResult()
với ý định được phương thức
createScreenCaptureIntent()
của dịch vụ hệ thống MediaProjectionManager
trả về:
Kotlin
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION)
Java
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION);
Lệnh gọi sẽ hiển thị hộp thoại xác nhận để thông báo cho người dùng rằng tính năng chiếu nội dung nghe nhìn chụp lại mọi thông tin hiển thị, bao gồm bất kỳ thông tin nhạy cảm hoặc thông tin nhận dạng cá nhân nào.
Nếu người dùng xác nhận thì startActivityForResult()
sẽ truyền một mã kết quả và dữ liệu đến lệnh gọi lại
onActivityResult()
.
Sau đó, bạn có thể truyền dữ liệu và mã kết quả đến phương thức
getMediaProjection()
từ MediaProjectionManager
để tạo một thực thể của MediaProjection
:
Kotlin
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, resultData)
Java
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, resultData);
Phương pháp đề xuất
Phương pháp này khuyến khích bạn sử dụng API từ thư viện Hoạt động Jetpack để lấy mã thông báo chiếu nội dung nghe nhìn:
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()); } } );
Màn hình ảo
Tâm điểm của tính năng chiếu nội dung nghe nhìn là màn hình ảo mà bạn tạo bằng cách gọi
createVirtualDisplay()
cho thực thể 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);
Các tham số width
và height
chỉ định chiều rộng và chiều cao của màn hình ảo. Để có được các giá trị khớp với chiều rộng và chiều cao của hình chiếu nội dung nghe nhìn, hãy sử dụng các API WindowMetrics
được giới thiệu trong Android 11 (API cấp 30).
WindowMetrics
Phép chiếu nội dung nghe nhìn sẽ chụp lại toàn bộ màn hình, bất kể ứng dụng có đang tạo phép chiếu nội dung nghe nhìn ở chế độ toàn màn hình hay ở chế độ nhiều cửa sổ hay không.
Để có kích thước của một phép chiếu nội dung nghe nhìn, hãy sử dụng WindowManager#getMaximumWindowMetrics()
, theo đó trả về WindowMetrics
cho đối tượng toàn màn hình ngay cả khi ứng dụng chiếu nội dung nghe nhìn ở chế độ nhiều cửa sổ, chỉ chiếm một phần màn hình.
Để tương thích xuống đến API cấp 14, hãy sử dụng WindowMetricsCalculator#computeMaximumWindowMetrics()
từ thư viện Jetpack WindowManager.
Gọi WindowMetrics#getBounds()
để lấy kích thước chiều rộng và chiều cao chính xác cho màn hình ảo của hình chiếu nội dung nghe nhìn (xem Màn hình ảo).
Kích thước ứng dụng chiếu nội dung nghe nhìn phải luôn có thể đổi kích thước. Các ứng dụng có thể thay đổi kích thước hỗ trợ thay đổi cấu hình thiết bị và chế độ nhiều cửa sổ (xem phần Hỗ trợ nhiều cửa sổ).
Nếu ứng dụng không thể thay đổi kích thước thì nó phải truy vấn các ranh giới hiển thị của cửa sổ và truy xuất WindowMetrics
của khu vực hiển thị tối đa có sẵn cho ứng dụng bằng WindowManager#getMaximumWindowMetrics()
:
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();
Bề mặt
Bạn nên định kích thước bề mặt chiếu nội dung nghe nhìn để có đầu ra ở độ phân giải mong muốn. Kích thước lớn (độ phân giải thấp) để truyền sang TV hoặc màn hình máy tính và kích thước nhỏ (độ phân giải cao) để quay màn hình thiết bị.
Kể từ 12L (API cấp 32), khi hệ thống kết xuất màn hình ảo trên bề mặt, hệ thống sẽ điều chỉnh tỷ lệ màn hình ảo sao cho vừa với bề mặt bằng quy trình tương tự như tuỳ chọn
centerInside
trong ImageView
.
Phương pháp điều chỉnh tỷ lệ mới cải thiện tính năng truyền màn hình sang TV và các màn hình lớn khác bằng cách tối đa hoá kích thước của hình ảnh bề mặt trong khi vẫn đảm bảo tỷ lệ khung hình phù hợp.
Đề xuất
Để có kết quả tốt nhất khi chiếu nội dung nghe nhìn, hãy thực hiện theo các đề xuất sau:
- Ứng dụng phải có thể thay đổi kích thước. Các ứng dụng có thể thay đổi kích thước hỗ trợ thay đổi cấu hình thiết bị và chế độ nhiều cửa sổ (xem phần
Hỗ trợ nhiều cửa sổ). Trong tệp kê khai ứng dụng, hãy đặt
resizeableActivity="true"
. Trên Android 7.0 (API cấp 24) trở lên, chế độ cài đặt này có giá trị mặc định là đúng. - Cho phép các ứng dụng của bạn hỗ trợ hướng ngang và hướng dọc vì cả hai hướng đều phổ biến trên điện thoại, máy tính bảng và các dạng thức có thể gập.
- Sử dụng
WindowManager#getMaximumWindowMetrics()
để lấy ranh giới của hình chiếu nội dung nghe nhìn. Để tương thích xuống cấp API 14, hãy sử dụng Jetpack WindowManager. (Xem mục WindowMetrics). - Nếu ứng dụng không thể thay đổi kích thước, hãy lấy ranh giới hình chiếu nội dung nghe nhìn thông qua ranh giới cửa sổ. (Xem mục WindowMetrics).
Tài nguyên khác
Để biết thêm thông tin về phép chiếu nội dung nghe nhìn, vui lòng xem nội dung Quay video và phát lại âm thanh.