Add comments and README.md file to Android tutorial

This commit is contained in:
juancarmore 2024-07-27 13:48:38 +02:00
parent c3b9d3c5f8
commit 2fd5c8f9fa
4 changed files with 61 additions and 8 deletions

View File

@ -0,0 +1,21 @@
# Basic Android
Basic client application built for Android using Kotlin. It internally uses [livekit-client-sdk-android](https://docs.livekit.io/client-sdk-js/).
For further information, check the [tutorial documentation](https://livekit-tutorials.openvidu.io/tutorials/application-client/android/).
## Prerequisites
- [Android Studio](https://developer.android.com/studio)
## Run
1. Download repository
```bash
git clone https://github.com/OpenVidu/openvidu-livekit-tutorials.git
```
2. Open Android Studio and import the project `openvidu-livekit-tutorials/application-client/openvidu-android`
3. Run the application in an emulator or a physical device by clicking the `Run` button in Android Studio. Check out the [official documentation](https://developer.android.com/studio/run) for further information.

View File

@ -3,6 +3,7 @@ package io.openvidu.android
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import io.openvidu.android.databinding.ActivityMainBinding
@ -11,6 +12,7 @@ import io.openvidu.android.databinding.DialogSettingsBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
// Configure this variables with correct URLs depending on your deployment
private var applicationServerUrl = "https://{YOUR-LAN-IP}.openvidu-local.dev:6443/"
private var livekitUrl = "wss://{YOUR-LAN-IP}.openvidu-local.dev:7443/"
@ -43,11 +45,17 @@ class MainActivity : AppCompatActivity() {
intent.putExtra("serverUrl", applicationServerUrl)
intent.putExtra("livekitUrl", livekitUrl)
startActivity(intent)
} else {
Toast.makeText(this, "Please fill in all fields", Toast.LENGTH_SHORT).show()
}
binding.joinButton.isEnabled = true
}
/**
* This dialog allows to change the LiveKit URL and the application server URL
* from the application itself. This is useful for development purposes.
*/
private fun showSettingsDialog() {
val dialogBinding = DialogSettingsBinding.inflate(LayoutInflater.from(this))

View File

@ -18,6 +18,7 @@ class ParticipantViewHolder(private val binding: ParticipantItemBinding) :
binding.identity.text = participantIdentity
// Only initialize the renderer once
if (!used) {
room.initVideoRenderer(binding.renderer)
used = true

View File

@ -65,10 +65,12 @@ class RoomLayoutActivity : AppCompatActivity() {
APPLICATION_SERVER_URL = intent.getStringExtra("serverUrl") ?: ""
LIVEKIT_URL = intent.getStringExtra("livekitUrl") ?: ""
// Create Room object.
// Create Room object
room = LiveKit.create(applicationContext)
initRecyclerView()
// Check for audio and camera permissions before connecting to the room
requestNeededPermissions { connectToRoom() }
}
@ -79,17 +81,20 @@ class RoomLayoutActivity : AppCompatActivity() {
}
private fun connectToRoom() {
val participantName = intent.getStringExtra("participantName") ?: "Participant 1"
// Get the room name and participant name from the intent
val participantName = intent.getStringExtra("participantName") ?: "Participant1"
val roomName = intent.getStringExtra("roomName") ?: "Test Room"
binding.roomName.text = roomName
lifecycleScope.launch {
// Setup event handling.
// Specify the actions when events take place in the room
launch {
room.events.collect { event ->
when (event) {
// On every new Track received...
is RoomEvent.TrackSubscribed -> onTrackSubscribed(event)
// On every new Track destroyed...
is RoomEvent.TrackUnsubscribed -> onTrackUnsubscribed(event)
else -> {}
}
@ -97,18 +102,18 @@ class RoomLayoutActivity : AppCompatActivity() {
}
try {
// Get token from server.
// Get token from your application server with the room name and participant name
val token = getToken(roomName, participantName)
// Connect to server.
// Connect to the room with the LiveKit URL and the token
room.connect(LIVEKIT_URL, token)
// Turn on audio/video recording.
// Publish your camera and microphone
val localParticipant = room.localParticipant
localParticipant.setMicrophoneEnabled(true)
localParticipant.setCameraEnabled(true)
// Add local video track to the participantTracks list.
// Add local video track to the participantTracks list
launch {
localParticipant::videoTrackPublications.flow
.collect { publications ->
@ -137,6 +142,7 @@ class RoomLayoutActivity : AppCompatActivity() {
private fun onTrackSubscribed(event: RoomEvent.TrackSubscribed) {
val track = event.track
// If the track is a video track, add it to the participantTracks list
if (track is VideoTrack) {
participantTracks.add(TrackInfo(track, event.participant.identity!!.value))
participantAdapter.notifyItemInserted(participantTracks.size - 1)
@ -146,6 +152,7 @@ class RoomLayoutActivity : AppCompatActivity() {
private fun onTrackUnsubscribed(event: RoomEvent.TrackUnsubscribed) {
val track = event.track
// If the track is a video track, remove it from the participantTracks list
if (track is VideoTrack) {
val index = participantTracks.indexOfFirst { it.track.sid == track.sid }
@ -157,8 +164,11 @@ class RoomLayoutActivity : AppCompatActivity() {
}
private fun leaveRoom() {
// Leave the room by calling 'disconnect' method over the Room object
room.disconnect()
client.close()
// Go back to the previous activity.
finish()
}
@ -173,7 +183,7 @@ class RoomLayoutActivity : AppCompatActivity() {
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { grants ->
var hasDenied = false
// Check if any permissions weren't granted.
// Check if any permissions weren't granted
for (grant in grants.entries) {
if (!grant.value) {
Toast.makeText(this, "Missing permission: ${grant.key}", Toast.LENGTH_SHORT)
@ -203,6 +213,19 @@ class RoomLayoutActivity : AppCompatActivity() {
}
}
/**
* --------------------------------------------
* GETTING A TOKEN FROM YOUR APPLICATION SERVER
* --------------------------------------------
* The method below request the creation of a token to
* your application server. This prevents the need to expose
* your LiveKit API key and secret to the client side.
*
* In this sample code, there is no user control at all. Anybody could
* access your application server endpoints. In a real production
* environment, your application server must identify the user to allow
* access to the endpoints.
*/
private suspend fun getToken(roomName: String, participantName: String): String {
val response = client.post(APPLICATION_SERVER_URL + "token") {
contentType(ContentType.Application.Json)