@@ -14,11 +14,8 @@ To handle deep links in Android you need to declare an intent filter in `android
1414<activity
1515 android : name =" .MainActivity"
1616 android : exported =" true" >
17- <intent-filter
18- android : autoVerify =" true"
19- android : label =" Call Link" >
17+ <intent-filter android : autoVerify =" true" android : label =" call_link" >
2018 <action android : name =" android.intent.action.VIEW" />
21-
2219 <category android : name =" android.intent.category.DEFAULT" />
2320 <category android : name =" android.intent.category.BROWSABLE" />
2421 <data
@@ -101,9 +98,11 @@ In its simplest form, your AASA file should have the following format:
10198}
10299```
103100
104- You can also specify exact paths if you want to have stricter control over which ones can invoke your app. You can also specify several apps on the same domain.
101+ You can also specify exact paths if you want to have stricter control over which ones can invoke your app.
102+ You can also specify several apps on the same domain.
105103
106- Before proceeding, please make sure that the uploaded file is a valid one, and it's deployed at the right place. For this, you can use Apple's [ validation tool] ( https://search.developer.apple.com/appsearch-validation-tool ) .
104+ Before proceeding, please make sure that the uploaded file is a valid one, and it's deployed at the right place.
105+ For this, you can use Apple's [ validation tool] ( https://search.developer.apple.com/appsearch-validation-tool ) .
107106
108107## Handling deep links
109108
@@ -118,52 +117,61 @@ dependencies:
118117Next, use the snippet below to listen for incoming deep links and navigate to ` JoinScreen` that we'll cover in the next step:
119118
120119` ` ` dart
120+ import 'package:uni_links/uni_links.dart';
121+
122+ StreamSubscription<Uri?>? _deepLinkSubscription;
123+
121124Future<void> _observeDeepLinks() async {
122- // 1
125+ // The app was in the background.
126+ if (!kIsWeb) {
127+ _deepLinkSubscription = uriLinkStream.listen((uri) {
128+ if (mounted && uri != null) _handleDeepLink(uri);
129+ });
130+ }
131+
132+ // The app was terminated.
123133 try {
124134 final initialUri = await getInitialUri();
125- if (initialUri != null) {
126- await _handleDeepLink(initialUri);
127- }
135+ if (initialUri != null) _handleDeepLink(initialUri);
128136 } catch (e) {
129137 debugPrint(e.toString());
130138 }
131-
132- // 2
133- if (!kIsWeb) {
134- _subscription = uriLinkStream.listen((Uri? uri) {
135- if (mounted && uri != null) {
136- _handleDeepLink(uri);
137- }
138- });
139- }
140139}
141140
142141Future<void> _handleDeepLink(Uri uri) async {
143- // 3
144- final callId = uri.pathSegments.last;
145-
146- // 4
147- Navigator.of(context).push(
148- MaterialPageRoute(
149- builder: (context) {
150- return JoinScreen(
151- callId: callId,
152- );
153- },
154- ),
155- );
142+ // Parse the call id from the deep link.
143+ final callId = uri.queryParameters['id'];
144+ if (callId == null) return;
145+
146+ // return if the video user is not yet logged in.
147+ // Replace the getCurrentUser() method with your method to retrieve the current user
148+ final currentUser = getCurrentUser();
149+ if (currentUser == null) return;
150+
151+ final streamVideo = StreamVideo.instance;
152+ final call = streamVideo.makeCall(type: kCallType, id: callId);
153+
154+ try {
155+ await call.getOrCreate();
156+ } catch (e, stk) {
157+ debugPrint('Error joining or creating call: $e');
158+ debugPrint(stk.toString());
159+ return;
160+ }
161+
162+ // Your method to navigate to the lobby/call screen.
163+ navigateToCallScreen();
156164}
157165` ` `
158166
159167In this snippet, you :
160168
161- 1. Handle the case when the app was terminated and is now started by a deep link.
162- 2. Handle the case when the app was in the background and is now brought to the foreground by a deep link.
169+ 1. Handle the case when the app was in the background and is now brought to the foreground by a deep link.
170+ 2. Handle the case when the app was terminated and is now started by a deep link.
1631713. Extract the call ID from the deep link URL.
164- 4. Navigate to a screen that will handle call initialization .
172+ 4. Navigate to a screen that will handle the call .
165173
166- Finally, add `JoinScreen` with the call initialization :
174+ While you can initialize the call on your call screen, you can also add an intermediary `JoinScreen` with the call initialization :
167175
168176` ` ` dart
169177class JoinScreen extends StatefulWidget {
@@ -184,9 +192,10 @@ class _JoinScreenState extends State<JoinScreen> {
184192 @override
185193 void initState() {
186194 super.initState();
187- _initCall (widget.callId);
195+ _joinCall (widget.callId);
188196 }
189197
198+ // Step 1
190199 @override
191200 Widget build(BuildContext context) {
192201 return Scaffold(
@@ -196,45 +205,25 @@ class _JoinScreenState extends State<JoinScreen> {
196205 body: Center(
197206 child: _isInProgress
198207 ? const CircularProgressIndicator(
199- strokeWidth: 2,
200- )
208+ strokeWidth: 2,
209+ )
201210 : const SizedBox(),
202211 ),
203212 );
204213 }
205214
206- Future<void> _initCall(String callId) async {
207- await _logIn();
208- await _joinCall(widget.callId);
209- }
210-
211- // 1
212- Future<void> _logIn() async {
213- final userCredentials = await UserRepository.instance.getUserCredentials();
214-
215- if (userCredentials != null) {
216- final user = userCredentials.user;
217- final token = userCredentials.token;
218-
219- await StreamVideo.instance.connectUser(
220- user,
221- token: Token(token),
222- );
223- }
224- }
225-
226- // 2
215+ // Step 2
227216 Future<void> _joinCall(String callId) async {
228217 setState(() => _isInProgress = true);
229218
230219 try {
231- final call = await StreamVideo.instance.joinCall (
220+ final call = StreamVideo.instance.makeCall (
232221 id: callId,
233222 type: 'default',
234223 );
235224
236225 await call.join();
237-
226+
238227 await _navigateToCall(call);
239228 } catch (e) {
240229 debugPrint(e.toString());
@@ -243,28 +232,18 @@ class _JoinScreenState extends State<JoinScreen> {
243232 }
244233 }
245234
246- // 3
235+ // Step 3
247236 Future<void> _navigateToCall(Call call) async {
248- await Navigator.of(context).push(
249- MaterialPageRoute(
250- builder: (context) {
251- return StreamCallScreen(
252- call: call,
253- onBackPressed: navigateHome,
254- onHangUp: navigateHome,
255- );
256- },
257- ),
258- );
237+ // Navigate to your call screen
259238 }
260239}
261240` ` `
262241
263242Here's what you're doing here, step-by-step :
264243
265- 1. Connecting the user from your persistence storage to the Video API .
244+ 1. Showing a connecting screen for the call while it initializes .
2662452. Joining the call with the call ID from the deep link.
267- 3. Navigating to `StreamCallScreen` from our SDK .
246+ 3. Navigating to your call screen .
268247
269248# # Testing deep links
270249
0 commit comments