system_helper.dart 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. import 'package:get/get.dart';
  2. import 'package:url_launcher/url_launcher.dart';
  3. import '../app/components/ix_snackbar.dart';
  4. import '../app/constants/configs.dart';
  5. import '../app/controllers/base_core_api.dart';
  6. import '../app/data/sp/ix_sp.dart';
  7. import '../app/routes/app_pages.dart';
  8. import 'package:flutter_custom_tabs/flutter_custom_tabs.dart' as ct;
  9. import '../config/translations/strings_enum.dart';
  10. class SystemHelper {
  11. // static Future<void> openEmail(String email) async {
  12. // final Uri emailUri = Uri(
  13. // scheme: 'mailto',
  14. // path: email,
  15. // );
  16. // try {
  17. // await launchUrl(
  18. // emailUri,
  19. // mode: LaunchMode.externalApplication,
  20. // );
  21. // } catch (e) {
  22. // CustomSnackBar.showCustomErrorSnackBar(
  23. // title: Strings.error.tr, message: Strings.eUtilOpenEmail.tr);
  24. // }
  25. // }
  26. static Future<void> openGooglePlay(String packageName) async {
  27. final String url =
  28. 'https://play.google.com/store/apps/details?id=$packageName';
  29. try {
  30. // 直接尝试打开 Google Play 应用
  31. await launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication);
  32. } catch (e) {
  33. IXSnackBar.showIXErrorSnackBar(
  34. title: Strings.error.tr,
  35. message: Strings.eUtilOpenGooglePlay.tr,
  36. );
  37. }
  38. }
  39. static Future<void> openGooglePlayUrl(String url) async {
  40. try {
  41. // 直接尝试打开 Google Play 应用
  42. await launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication);
  43. } catch (e) {
  44. IXSnackBar.showIXErrorSnackBar(
  45. title: Strings.error.tr,
  46. message: Strings.eUtilOpenGooglePlay.tr,
  47. );
  48. }
  49. }
  50. static Future<void> openGoogleChrome(String url) async {
  51. try {
  52. await ct.launchUrl(
  53. Uri.parse(url),
  54. customTabsOptions: ct.CustomTabsOptions.partial(
  55. configuration: ct.PartialCustomTabsConfiguration.adaptiveSheet(
  56. initialHeight: Get.height * 0.7,
  57. initialWidth: Get.width * 0.4,
  58. activitySideSheetMaximizationEnabled: true,
  59. activitySideSheetDecorationType:
  60. ct.CustomTabsActivitySideSheetDecorationType.shadow,
  61. activitySideSheetRoundedCornersPosition:
  62. ct.CustomTabsActivitySideSheetRoundedCornersPosition.top,
  63. cornerRadius: 16,
  64. ),
  65. ),
  66. safariVCOptions: const ct.SafariViewControllerOptions.pageSheet(
  67. configuration: ct.SheetPresentationControllerConfiguration(
  68. detents: {
  69. ct.SheetPresentationControllerDetent.large,
  70. ct.SheetPresentationControllerDetent.medium,
  71. },
  72. prefersScrollingExpandsWhenScrolledToEdge: true,
  73. prefersGrabberVisible: true,
  74. prefersEdgeAttachedInCompactHeight: true,
  75. ),
  76. dismissButtonStyle: ct.SafariViewControllerDismissButtonStyle.close,
  77. ),
  78. );
  79. } catch (e) {
  80. try {
  81. await launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication);
  82. } catch (e) {
  83. IXSnackBar.showIXErrorSnackBar(
  84. title: Strings.error.tr,
  85. message: Strings.eUtilOpenBrowser.tr,
  86. );
  87. }
  88. }
  89. }
  90. static Future<void> closeGoogleChrome() async {
  91. await ct.closeCustomTabs();
  92. }
  93. static Future<void> openWebPage(String url) async {
  94. try {
  95. final Uri webUri = Uri.parse(url);
  96. await launchUrl(webUri, mode: LaunchMode.externalApplication);
  97. } catch (e) {
  98. IXSnackBar.showIXErrorSnackBar(
  99. title: Strings.error.tr,
  100. message: Strings.eUtilOpenBrowser.tr,
  101. );
  102. }
  103. }
  104. static Future<void> openInAppWebPage(String url, String title) async {
  105. Get.toNamed(Routes.WEB, arguments: {'url': url, 'title': title});
  106. }
  107. static Future<void> handleDeepLink(String deepLink) async {
  108. try {
  109. final Uri uri = Uri.parse(deepLink);
  110. if (await canLaunchUrl(uri)) {
  111. await launchUrl(uri, mode: LaunchMode.externalApplication);
  112. } else {
  113. IXSnackBar.showIXErrorSnackBar(
  114. title: Strings.error.tr,
  115. message: Strings.unknownError.tr,
  116. );
  117. }
  118. } catch (e) {
  119. IXSnackBar.showIXErrorSnackBar(
  120. title: Strings.error.tr,
  121. message: Strings.unknownError.tr,
  122. );
  123. }
  124. }
  125. static Future<void> openPackage(String packageName) async {
  126. try {
  127. await BaseCoreApi().openPackage(packageName);
  128. } catch (e) {
  129. IXSnackBar.showIXErrorSnackBar(
  130. title: Strings.error.tr,
  131. message: Strings.unknownError.tr,
  132. );
  133. }
  134. }
  135. static void openPrivacyTerms() {
  136. final launch = IXSP.getLaunch();
  137. if (launch?.appConfig?.privacyAgreement != null &&
  138. launch?.appConfig?.privacyAgreement?.privacyTermsUrl != null) {
  139. String url = launch?.appConfig?.privacyAgreement?.privacyTermsUrl ?? '';
  140. if (url.indexOf("http") != 0) {
  141. url = '${Configs.websiteUrl}/$url';
  142. }
  143. Get.toNamed(
  144. Routes.WEB,
  145. arguments: {'url': url, 'title': Strings.privacyPolicy.tr},
  146. );
  147. } else {
  148. Get.toNamed(
  149. Routes.MARKDOWN,
  150. arguments: {'title': Strings.privacyPolicy.tr, 'filename': 'privacy'},
  151. );
  152. }
  153. }
  154. static void openTermsOfService() {
  155. final launch = IXSP.getLaunch();
  156. if (launch?.appConfig?.privacyAgreement != null &&
  157. launch?.appConfig?.privacyAgreement?.termsOfServiceUrl != null) {
  158. String url = launch?.appConfig?.privacyAgreement?.termsOfServiceUrl ?? '';
  159. if (url.indexOf("http") != 0) {
  160. url = '${Configs.websiteUrl}/$url';
  161. }
  162. Get.toNamed(
  163. Routes.WEB,
  164. arguments: {'url': url, 'title': Strings.termsOfService.tr},
  165. );
  166. } else {
  167. Get.toNamed(
  168. Routes.MARKDOWN,
  169. arguments: {'title': Strings.termsOfService.tr, 'filename': 'terms'},
  170. );
  171. }
  172. }
  173. // 打开 JS Bridge 测试页面
  174. static void openTestPage() {
  175. Get.toNamed(
  176. Routes.WEB,
  177. arguments: {
  178. // 使用 assets/ 前缀,WebView 会自动使用 loadData 加载
  179. 'url': 'assets/html/test_jsbridge.html',
  180. 'title': 'JS Bridge 测试',
  181. 'fullScreen': true,
  182. },
  183. );
  184. }
  185. }