Files
jinzhi/lib/common/util/app_link_util.dart
T
jingyun 3b089e2205 feat: 对齐常驻商城与七鱼客服交互
- 同步商城 H5 登录态与原生 token
- 完善商城/原生 tab 切换、动画及返回交互
- 修复七鱼客服键盘避让和状态栏恢复
- 调整开屏跳过按钮与登录入口交互
2026-09-07 15:47:01 +08:00

61 lines
1.9 KiB
Dart

import 'dart:io' show Platform;
import 'package:android_intent_plus/android_intent.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:url_launcher/url_launcher.dart';
typedef AndroidIntentLauncher = Future<void> Function(AndroidIntent intent);
abstract final class AppLinkUtil {
static final _androidPackageNamePattern = RegExp(
r'^[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)+$',
);
static String targetAppFromUrl(String urlString) {
final value = Uri.tryParse(urlString)?.queryParameters['targetApp']?.trim();
if (value == null || !_androidPackageNamePattern.hasMatch(value)) return '';
return value;
}
static Future<bool> openExternal(Uri uri, {String packageName = ''}) =>
AppLinkLauncher(
isAndroid: () => !kIsWeb && Platform.isAndroid,
launchAndroidIntent: (intent) => intent.launch(),
).openExternal(uri, packageName: packageName);
}
class AppLinkLauncher {
const AppLinkLauncher({
required this.isAndroid,
required this.launchAndroidIntent,
this.launchExternal,
});
final bool Function() isAndroid;
final AndroidIntentLauncher launchAndroidIntent;
final Future<bool> Function(Uri uri)? launchExternal;
Future<bool> openExternal(Uri uri, {String packageName = ''}) async {
if (uri.host.isEmpty ||
(uri.scheme.toLowerCase() != 'http' &&
uri.scheme.toLowerCase() != 'https')) {
return false;
}
if (isAndroid() && packageName.trim().isNotEmpty) {
try {
await launchAndroidIntent(
AndroidIntent(
action: 'action_view',
data: uri.toString(),
package: packageName.trim(),
),
);
return true;
} catch (_) {}
}
final launcher = launchExternal;
if (launcher != null) return launcher(uri);
return launchUrl(uri, mode: LaunchMode.externalApplication);
}
}