Skip to content

Commit 79441ea

Browse files
Merge branch 'develop'
2 parents db3ccde + ba0f534 commit 79441ea

File tree

23 files changed

+379
-657
lines changed

23 files changed

+379
-657
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ If you're interested in customizing the UI components for the Video SDK, check o
4444
You can find sample projects below that demonstrates use cases of Stream Video SDK for Android:
4545

4646
- [Demo App](https://github.com/GetStream/stream-video-android/tree/develop/demo-app): Demo App demonstrates Stream Video SDK for Android with modern Android tech stacks, such as Compose, Hilt, and Coroutines.
47+
- [Android Video Samples](https://github.com/GetStream/Android-Video-Samples): Provides a collection of samples that utilize modern Android tech stacks and Stream Video SDK for Kotlin and Compose.
4748
- [WhatsApp Clone Compose](https://github.com/getstream/whatsapp-clone-compose): WhatsApp clone project demonstrates modern Android development built with Jetpack Compose and Stream Chat/Video SDK for Compose.
4849
- [Twitch Clone Compose](https://github.com/skydoves/twitch-clone-compose): Twitch clone project demonstrates modern Android development built with Jetpack Compose and Stream Chat/Video SDK for Compose.
4950
- [Meeting Room Compose](https://github.com/GetStream/meeting-room-compose): A real-time meeting room app built with Jetpack Compose to demonstrate video communications.

buildSrc/src/main/kotlin/io/getstream/video/android/Configuration.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ object Configuration {
66
const val minSdk = 24
77
const val majorVersion = 0
88
const val minorVersion = 5
9-
const val patchVersion = 7
9+
const val patchVersion = 8
1010
const val versionName = "$majorVersion.$minorVersion.$patchVersion"
11-
const val versionCode = 21
11+
const val versionCode = 22
1212
const val snapshotVersionName = "$majorVersion.$minorVersion.${patchVersion + 1}-SNAPSHOT"
1313
const val artifactGroup = "io.getstream"
14-
const val streamVideoCallGooglePlayVersion = "1.0.9"
14+
const val streamVideoCallGooglePlayVersion = "1.0.10"
1515
const val streamWebRtcVersionName = "1.1.1"
1616
}

demo-app/src/main/AndroidManifest.xml

Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -51,33 +51,6 @@
5151
</intent-filter>
5252
</activity>
5353

54-
<activity
55-
android:name="io.getstream.video.android.ui.call.CallActivity"
56-
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
57-
android:exported="true"
58-
android:launchMode="singleTask"
59-
android:hardwareAccelerated="true"
60-
android:supportsPictureInPicture="true"
61-
android:windowSoftInputMode="adjustResize">
62-
<intent-filter android:priority="1">
63-
<action android:name="io.getstream.video.android.action.ONGOING_CALL" />
64-
</intent-filter>
65-
</activity>
66-
67-
<activity
68-
android:name="io.getstream.video.android.IncomingCallActivity"
69-
android:exported="false"
70-
android:showOnLockScreen="true"
71-
android:showWhenLocked="true"
72-
android:supportsPictureInPicture="true">
73-
<intent-filter android:priority="1">
74-
<action android:name="io.getstream.video.android.action.INCOMING_CALL" />
75-
<action android:name="io.getstream.video.android.action.NOTIFICATION" />
76-
<action android:name="io.getstream.video.android.action.LIVE_CALL" />
77-
<action android:name="io.getstream.video.android.action.ACCEPT_CALL" />
78-
</intent-filter>
79-
</activity>
80-
8154
<activity
8255
android:name=".DeeplinkingActivity"
8356
android:exported="true"
@@ -99,13 +72,18 @@
9972
</activity>
10073

10174
<activity
102-
android:name="io.getstream.video.android.DirectCallActivity"
103-
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
104-
android:exported="true"
105-
android:hardwareAccelerated="true"
75+
android:name=".CallActivity"
10676
android:supportsPictureInPicture="true"
107-
android:windowSoftInputMode="adjustResize">
77+
android:showOnLockScreen="true"
78+
android:showWhenLocked="true"
79+
android:launchMode="singleTop"
80+
android:exported="false">
10881
<intent-filter android:priority="1">
82+
<action android:name="io.getstream.video.android.action.INCOMING_CALL" />
83+
<action android:name="io.getstream.video.android.action.NOTIFICATION" />
84+
<action android:name="io.getstream.video.android.action.LIVE_CALL" />
85+
<action android:name="io.getstream.video.android.action.ONGOING_CALL" />
86+
<action android:name="io.getstream.video.android.action.ACCEPT_CALL" />
10987
<action android:name="io.getstream.video.android.action.OUTGOING_CALL" />
11088
</intent-filter>
11189
</activity>
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright (c) 2014-2024 Stream.io Inc. All rights reserved.
3+
*
4+
* Licensed under the Stream License;
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://github.com/GetStream/stream-video-android/blob/main/LICENSE
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.getstream.video.android
18+
19+
import android.content.Intent
20+
import androidx.compose.runtime.Composable
21+
import androidx.compose.runtime.LaunchedEffect
22+
import androidx.compose.runtime.collectAsState
23+
import androidx.compose.runtime.getValue
24+
import io.getstream.chat.android.client.ChatClient
25+
import io.getstream.chat.android.models.Filters
26+
import io.getstream.chat.android.models.querysort.QuerySortByField
27+
import io.getstream.result.onSuccessSuspend
28+
import io.getstream.video.android.compose.ui.ComposeStreamCallActivity
29+
import io.getstream.video.android.compose.ui.StreamCallActivityComposeDelegate
30+
import io.getstream.video.android.core.Call
31+
import io.getstream.video.android.ui.call.CallScreen
32+
import io.getstream.video.android.ui.common.StreamActivityUiDelegate
33+
import io.getstream.video.android.ui.common.StreamCallActivity
34+
import io.getstream.video.android.ui.common.StreamCallActivityConfiguration
35+
import io.getstream.video.android.ui.common.util.StreamCallActivityDelicateApi
36+
import io.getstream.video.android.util.FullScreenCircleProgressBar
37+
38+
@OptIn(StreamCallActivityDelicateApi::class)
39+
class CallActivity : ComposeStreamCallActivity() {
40+
41+
override val uiDelegate: StreamActivityUiDelegate<StreamCallActivity> = StreamDemoUiDelegate()
42+
override val configuration: StreamCallActivityConfiguration =
43+
StreamCallActivityConfiguration(closeScreenOnCallEnded = false)
44+
45+
private class StreamDemoUiDelegate : StreamCallActivityComposeDelegate() {
46+
47+
@Composable
48+
override fun StreamCallActivity.LoadingContent(call: Call) {
49+
// Use as loading screen.. so the layout is shown.
50+
if (call.type == "default") {
51+
VideoCallContent(call = call)
52+
} else {
53+
FullScreenCircleProgressBar(text = "Connecting...")
54+
}
55+
}
56+
57+
@Composable
58+
override fun StreamCallActivity.CallDisconnectedContent(call: Call) {
59+
goBackToMainScreen()
60+
}
61+
62+
@Composable
63+
override fun StreamCallActivity.VideoCallContent(call: Call) {
64+
CallScreen(
65+
call = call,
66+
showDebugOptions = BuildConfig.DEBUG,
67+
onCallDisconnected = {
68+
leave(call)
69+
goBackToMainScreen()
70+
},
71+
onUserLeaveCall = {
72+
leave(call)
73+
goBackToMainScreen()
74+
},
75+
)
76+
77+
// step 4 (optional) - chat integration
78+
val user by ChatClient.instance().clientState.user.collectAsState(initial = null)
79+
LaunchedEffect(key1 = user) {
80+
if (user != null) {
81+
val channel = ChatClient.instance().channel("videocall", call.id)
82+
channel.queryMembers(
83+
offset = 0,
84+
limit = 10,
85+
filter = Filters.neutral(),
86+
sort = QuerySortByField(),
87+
).await().onSuccessSuspend { members ->
88+
if (members.isNotEmpty()) {
89+
channel.addMembers(listOf(user!!.id)).await()
90+
} else {
91+
channel.create(listOf(user!!.id), emptyMap()).await()
92+
}
93+
}
94+
}
95+
}
96+
}
97+
98+
private fun StreamCallActivity.goBackToMainScreen() {
99+
if (!isFinishing) {
100+
val intent = Intent(this, MainActivity::class.java).apply {
101+
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
102+
}
103+
startActivity(intent)
104+
finish()
105+
}
106+
}
107+
}
108+
}

demo-app/src/main/kotlin/io/getstream/video/android/DeeplinkingActivity.kt

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import io.getstream.video.android.compose.theme.VideoTheme
4040
import io.getstream.video.android.core.StreamVideo
4141
import io.getstream.video.android.datastore.delegate.StreamUserDataStore
4242
import io.getstream.video.android.model.StreamCallId
43-
import io.getstream.video.android.ui.call.CallActivity
43+
import io.getstream.video.android.ui.common.StreamCallActivity
4444
import io.getstream.video.android.util.InitializedState
4545
import io.getstream.video.android.util.StreamVideoInitHelper
4646
import io.getstream.video.android.util.config.AppConfig
@@ -110,16 +110,17 @@ class DeeplinkingActivity : ComponentActivity() {
110110
joinCall(data, callId)
111111
} else {
112112
// first ask for push notification permission
113-
val manager = NotificationPermissionManager.createNotificationPermissionsManager(
114-
application = app,
115-
requestPermissionOnAppLaunch = { true },
116-
onPermissionStatus = {
117-
// we don't care about the result for demo purposes
118-
if (it != NotificationPermissionStatus.REQUESTED) {
119-
joinCall(data, callId)
120-
}
121-
},
122-
)
113+
val manager =
114+
NotificationPermissionManager.createNotificationPermissionsManager(
115+
application = app,
116+
requestPermissionOnAppLaunch = { true },
117+
onPermissionStatus = {
118+
// we don't care about the result for demo purposes
119+
if (it != NotificationPermissionStatus.REQUESTED) {
120+
joinCall(data, callId)
121+
}
122+
},
123+
)
123124
manager.start()
124125
}
125126
} else {
@@ -179,13 +180,10 @@ class DeeplinkingActivity : ComponentActivity() {
179180
if (it == InitializedState.FINISHED || it == InitializedState.FAILED) {
180181
if (StreamVideo.isInstalled) {
181182
val callId = StreamCallId(type = "default", id = cid)
182-
val intent = CallActivity.createIntent(
183+
val intent = StreamCallActivity.callIntent(
183184
context = this@DeeplinkingActivity,
184-
callId = callId,
185-
disableMicOverride = intent.getBooleanExtra(
186-
EXTRA_DISABLE_MIC_OVERRIDE,
187-
false,
188-
),
185+
cid = callId,
186+
clazz = CallActivity::class.java,
189187
).apply {
190188
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
191189
}

0 commit comments

Comments
 (0)