Thêm thao tác từ xa vào PiP

Nếu bạn muốn thêm các nút điều khiển (phát, tạm dừng, v.v.) vào cửa sổ PiP, hãy tạo một RemoteAction cho mỗi nút điều khiển mà bạn muốn thêm.

  1. Thêm hằng số cho các chế độ điều khiển thông báo truyền tin:
    // Constant for broadcast receiver
    const val ACTION_BROADCAST_CONTROL = "broadcast_control"
    
    // Intent extras for broadcast controls from Picture-in-Picture mode.
    const val EXTRA_CONTROL_TYPE = "control_type"
    const val EXTRA_CONTROL_PLAY = 1
    const val EXTRA_CONTROL_PAUSE = 2
  2. Tạo danh sách RemoteActions cho các nút điều khiển trong cửa sổ PiP.
  3. Tiếp theo, hãy thêm BroadcastReceiver và ghi đè onReceive() để đặt các thao tác của từng nút. Sử dụng DisposableEffect để đăng ký trình thu và các thao tác từ xa. Khi trình phát bị loại bỏ, hãy huỷ đăng ký trình thu.
    @RequiresApi(Build.VERSION_CODES.O)
    @Composable
    fun PlayerBroadcastReceiver(player: Player?) {
        val isInPipMode = rememberIsInPipMode()
        if (!isInPipMode || player == null) {
            // Broadcast receiver is only used if app is in PiP mode and player is non null
            return
        }
        val context = LocalContext.current
    
        DisposableEffect(player) {
            val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
                override fun onReceive(context: Context?, intent: Intent?) {
                    if ((intent == null) || (intent.action != ACTION_BROADCAST_CONTROL)) {
                        return
                    }
    
                    when (intent.getIntExtra(EXTRA_CONTROL_TYPE, 0)) {
                        EXTRA_CONTROL_PAUSE -> player.pause()
                        EXTRA_CONTROL_PLAY -> player.play()
                    }
                }
            }
            ContextCompat.registerReceiver(
                context,
                broadcastReceiver,
                IntentFilter(ACTION_BROADCAST_CONTROL),
                ContextCompat.RECEIVER_NOT_EXPORTED
            )
            onDispose {
                context.unregisterReceiver(broadcastReceiver)
            }
        }
    }
  4. Truyền danh sách các thao tác từ xa vào PictureInPictureParams.Builder:
    val context = LocalContext.current
    
    val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
        val builder = PictureInPictureParams.Builder()
        builder.setActions(
            listOfRemoteActions()
        )
    
        if (shouldEnterPipMode && player != null && player.videoSize != VideoSize.UNKNOWN) {
            val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect()
            builder.setSourceRectHint(sourceRect)
            builder.setAspectRatio(
                Rational(player.videoSize.width, player.videoSize.height)
            )
        }
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            builder.setAutoEnterEnabled(shouldEnterPipMode)
        }
        context.findActivity().setPictureInPictureParams(builder.build())
    }
    VideoPlayer(modifier = pipModifier)

Các bước tiếp theo

  • Hãy xem ứng dụng Socialite để biết các phương pháp hay nhất về cách sử dụng tính năng PiP trong Compose.
  • Hãy xem Hướng dẫn thiết kế PiP để biết thêm thông tin.