Kotlin

Solicitação de permissões

Como nosso aplicativo utiliza áudio e vídeo do dispositivo do usuário, precisaremos adicionar um código para solicitar permissões de áudio e vídeo. Usaremos o Accompanist para simplificar o processo.

  1. Adicionar permissões a AndroidManifest.xml

Dentro do seu AndroidManifest.xml, adicione o seguinte dentro do <manifest> tag:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />

ℹ️ Observação: O WAKE_LOCK Essa permissão é usada para impedir que o dispositivo entre no modo de suspensão durante uma videochamada. Isso garante a transmissão ininterrupta de mídia.

1a. Serviço de primeiro plano para projeção de mídia

A captura de tela deve ser executada dentro de um serviço em primeiro plano do tipo mediaProjection. Declare o serviço no seu manifesto:

<service
    android:name=".ScreenSharingService"
    android:exported="false"
    android:foregroundServiceType="mediaProjection"
    android:permission="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
  1. Adicionar dependências e permissões ao manifesto

Primeiro, adicione o Accompanist dependência do seu build.gradle arquivo:

dependencies {
   implementation("com.google.accompanist:accompanist-permissions:0.34.0")
}
  1. Implementar o gerenciamento de permissões no compose

Com Accompanist, usamos rememberMultiplePermissionsState. Isso permite que a interface do usuário React automaticamente quando as permissões são concedidas ou negadas. Crie um novo arquivo VideoChatPermissionWrapper.kt da seguinte forma:

@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun VideoChatPermissionWrapper(
    onPermissionsGranted: () -> Unit,
    content: @Composable () -> Unit
) {
    val permissionsState = rememberMultiplePermissionsState(
        permissions = listOf(
            Manifest.permission.CAMERA,
            Manifest.permission.RECORD_AUDIO
        )
    )

    if (permissionsState.allPermissionsGranted) {
        // 1. Notify parent that permissions are ready (run once)
        LaunchedEffect(Unit) {
            onPermissionsGranted()
        }
        // 2. Show the actual video UI
        content()
    } else {
        // 3. Show a Rationale UI if permissions are missing
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(16.dp),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(text = "Camera and Audio permissions are required for video chat.")

            Button(
                onClick = { permissionsState.launchMultiplePermissionRequest() },
                modifier = Modifier.padding(top = 16.dp)
            ) {
                Text("Grant Permissions")
            }
        }

        // Auto-launch the popup on the very first composition
        LaunchedEffect(Unit) {
            if (!permissionsState.allPermissionsGranted) {
                permissionsState.launchMultiplePermissionRequest()
            }
        }
    }
}
  1. Atualização MainActivity.kt & definir o initializeSession() método como um espaço reservado para a configuração da sua videochamada"

Agora, incorpore isso à sua MainActivity. Basta chamar seu VideoChatPermissionWrapper dentro do setContent.

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        enableEdgeToEdge()

        setContent {
            VideoChatPermissionWrapper(
                onPermissionsGranted = {
                    initializeSession(
                        appId = VonageVideoConfig.APP_ID,
                        sessionId = VonageVideoConfig.SESSION_ID,
                        token = VonageVideoConfig.TOKEN
                    )
                }
            ) {
                VideoChatScreen(
                    publisherView = publisherView,
                    subscriberView = subscriberView
                )
            }
        }
    }


    private fun initializeSession(appId: String, sessionId: String, token: String) {
        // TODO: Connect to Vonage session
    }
}
  1. Próximos passos

Assim que as permissões forem concedidas, o initializeSession() A função será acionada. Nas próximas etapas do tutorial, você implementará a lógica para se conectar a uma sessão da Video API do Vonage.