deep linking test

This commit is contained in:
mohamadmahdi jebeli 2025-07-14 10:59:17 +03:30
parent 047de45e3b
commit 86913a973b
4 changed files with 62 additions and 80 deletions

View File

@ -106,7 +106,7 @@
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="web.didvan.com" />
<data android:scheme="https" android:host="test.didvan.com" />
</intent-filter>
</activity>

View File

@ -3,8 +3,6 @@
import 'dart:async';
import 'dart:io';
import 'package:android_intent_plus/android_intent.dart';
import 'package:app_links/app_links.dart';
import 'package:bot_toast/bot_toast.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/firebase_options.dart';
@ -35,18 +33,19 @@ import 'package:provider/provider.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
// پکیج جدید برای Deep Linking
import 'package:app_links/app_links.dart';
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
// متغیر استاتیک برای نگهداری لینک اولیه
Uri? initialURI;
@pragma('vm:entry-point')
Future<void> _backgroundCallbackHomeWidget(Uri? uri) async {
await HomeWidget.saveWidgetData("uri", uri!.host);
AndroidIntent intent = const AndroidIntent(
action: 'android.intent.action.RUN',
package: 'com.didvan.didvanapp',
componentName: 'com.didvan.didvanapp.MainActivity',
);
await intent.launch();
return;
if (uri != null) {
await HomeWidget.saveWidgetData("uri", uri.host);
}
}
void main() async {
@ -59,10 +58,8 @@ void main() async {
try {
if (Platform.isAndroid) {
await FlutterDownloader.initialize(
debug:
true,
ignoreSsl:
true
debug: true,
ignoreSsl: true
);
}
} catch (e) {
@ -74,7 +71,7 @@ void main() async {
options: DefaultFirebaseOptions.currentPlatform);
await FirebaseApi().initNotification();
} catch (e) {
debugPrint;
debugPrint(e.toString());
}
await SentryFlutter.init(
@ -98,38 +95,33 @@ class Didvan extends StatefulWidget {
class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
late AppLinks _appLinks;
StreamSubscription<Uri>? _linkSubscription;
@override
void didChangeDependencies() {
super.didChangeDependencies();
}
@override
void initState() {
WidgetsBinding.instance.addObserver(this);
super.initState();
WidgetsBinding.instance.addObserver(this);
// مقداردهی اولیه و گوش دادن به لینکها در اینجا انجام میشود
_initDeepLinks();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
_linkSubscription?.cancel();
_linkSubscription?.cancel(); // لغو کردن subscription
if (MediaService.currentPodcast != null) {
MediaService.audioPlayer.dispose();
}
super.dispose();
}
/// منطق جدید برای مدیریت لینکها با app_links
Future<void> _initDeepLinks() async {
_appLinks = AppLinks();
// بررسی لینک اولیه در زمان باز شدن اپلیکیشن
final initialUri = await _appLinks.getInitialLink();
if (initialUri != null) {
_navigateTo(initialUri);
}
// لینک اولیه را فقط در متغیر ذخیره میکنیم
initialURI = await _appLinks.getInitialLink();
// گوش دادن به لینکهای جدید زمانی که اپلیکیشن در حال اجراست
// به لینکهای جدید زمانی که اپلیکیشن باز است گوش میدهیم
_linkSubscription = _appLinks.uriLinkStream.listen((uri) {
_navigateTo(uri);
});
@ -146,9 +138,6 @@ class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
}
}
bool b = true;
@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
if (!kIsWeb) {
@ -171,33 +160,15 @@ class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<PodcastsState>(
create: (context) => PodcastsState(),
),
ChangeNotifierProvider<MediaProvider>(
create: (context) => MediaProvider(),
),
ChangeNotifierProvider<UserProvider>(
create: (context) => UserProvider(),
),
ChangeNotifierProvider<ThemeProvider>(
create: (context) => ThemeProvider(),
),
ChangeNotifierProvider<StudioDetailsState>(
create: (context) => StudioDetailsState(),
),
ChangeNotifierProvider<HistoryAiChatState>(
create: (context) => HistoryAiChatState(),
),
ChangeNotifierProvider<AiState>(
create: (context) => AiState(),
),
ChangeNotifierProvider<AiChatState>(
create: (context) => AiChatState(),
),
ChangeNotifierProvider<BotAssistantsState>(
create: (context) => BotAssistantsState(),
),
ChangeNotifierProvider<PodcastsState>(create: (context) => PodcastsState()),
ChangeNotifierProvider<MediaProvider>(create: (context) => MediaProvider()),
ChangeNotifierProvider<UserProvider>(create: (context) => UserProvider()),
ChangeNotifierProvider<ThemeProvider>(create: (context) => ThemeProvider()),
ChangeNotifierProvider<StudioDetailsState>(create: (context) => StudioDetailsState()),
ChangeNotifierProvider<HistoryAiChatState>(create: (context) => HistoryAiChatState()),
ChangeNotifierProvider<AiState>(create: (context) => AiState()),
ChangeNotifierProvider<AiChatState>(create: (context) => AiChatState()),
ChangeNotifierProvider<BotAssistantsState>(create: (context) => BotAssistantsState()),
],
child: Consumer<ThemeProvider>(
builder: (context, themeProvider, child) => Container(
@ -243,4 +214,4 @@ class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
),
);
}
}
}

View File

@ -1,5 +1,3 @@
// ignore_for_file: deprecated_member_use
import 'package:didvan/config/design_config.dart';
import 'package:didvan/constants/assets.dart';
import 'package:didvan/main.dart';
@ -89,9 +87,6 @@ class _SplashState extends State<Splash> {
Future<void> _initialize(ThemeProvider themeProvider,
UserProvider userProvider, MediaProvider mediaProvider) async {
try {
// if (!kIsWeb) {
// await AppInitializer.onCheckUpdate(context);
// }
if (kIsWeb) {
html.window.onBeforeUnload.listen((event) {
StorageService.webStorage
@ -135,26 +130,29 @@ class _SplashState extends State<Splash> {
await ServerDataProvider.getData();
}
// --- بخش اصلاح شده ---
// ابتدا بررسی میکنیم که کاربر باید به کدام صفحه اصلی برود
final String destinationRoute = token == null ? Routes.authenticaion : Routes.home;
final dynamic routeArguments = token == null ? false : {'showDialogs': true};
navigatorKey.currentState!.pushReplacementNamed(
token == null ? Routes.authenticaion : Routes.home,
arguments: token == null ? false : null,
// اگر لینک ورودی وجود داشت، آن را به عنوان آرگومان به صفحه Home میفرستیم
if (destinationRoute == Routes.home && initialURI != null) {
(routeArguments as Map)['deepLinkUri'] = initialURI;
initialURI = null; // لینک را مصرف میکنیم تا دوباره استفاده نشود
}
// در نهایت به مسیر تعیین شده میرویم
await navigatorKey.currentState!.pushReplacementNamed(
destinationRoute,
arguments: routeArguments,
);
// --- پایان بخش اصلاح شده ---
return;
// await HomeWidget.getWidgetData<String>("cRouteGoTo", defaultValue: '')
// .then((cRouteGoTo) async {
// if (cRouteGoTo!.isNotEmpty) {
// navigatorKey.currentState!
// .pushNamed(cRouteGoTo.toString(), arguments:cRouteArgs );
// HomeWidget.saveWidgetData("cRouteGoTo", '');
// }
// });
} catch (e) {
setState(() {
_errorOccured = true;
});
}
}
}
}

View File

@ -0,0 +1,13 @@
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.didvan.didvanapp",
"sha256_cert_fingerprints": [
"02:5A:86:49:AE:B4:FF:FE:5B:D0:C6:D7:F9:FF:85:60:F0:CF:AE:2F:39:8C:9D:F6:0D:4A:41:5D:EA:07:BE:8B",
"CA:F0:F8:9D:6D:5C:70:A1:C0:E8:F6:4D:19:DA:49:12:D4:F9:D6:C1:DB:E7:1C:B5:4B:ED:F5:A5:AA:DA:EE:DB"
]
}
}
]