Hibok
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

496 Zeilen
17 KiB

  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'dart:io';
  4. import 'package:amap_location/amap_location.dart';
  5. import 'package:apple_sign_in/apple_sign_in.dart';
  6. import 'package:chat/data/WebData.dart';
  7. import 'package:chat/data/chat_data_mgr.dart';
  8. import 'package:chat/data/constants.dart';
  9. import 'package:chat/data/group_data_mgr.dart';
  10. import 'package:chat/home/homeMain.dart';
  11. import 'package:chat/home/splash_page.dart';
  12. import 'package:chat/models/gift_select_provider.dart';
  13. import 'package:chat/models/money_change.dart';
  14. import 'package:chat/models/ref_name_provider.dart';
  15. import 'package:chat/utils/LoadingDialog.dart';
  16. import 'package:chat/utils/MessageMgr.dart';
  17. import 'package:chat/utils/NetUtil.dart';
  18. import 'package:chat/utils/OtherLogin.dart';
  19. import 'package:chat/utils/file_cache_mgr.dart';
  20. import 'package:chat/utils/flutter_windowmanager.dart';
  21. import 'package:chat/utils/local_notification_util.dart';
  22. import 'package:chat/utils/msgHandler.dart';
  23. import 'package:chat/utils/receive_share_file.dart';
  24. import 'package:chat/utils/screen.dart';
  25. import 'package:chat/utils/screen_shot.dart';
  26. import 'package:chat/utils/sound_util.dart';
  27. import 'package:chat/utils/sp_utils.dart';
  28. import 'package:chat/utils/sql_util.dart';
  29. import 'package:easy_contact_picker/easy_contact_picker.dart';
  30. import 'package:flutter/cupertino.dart';
  31. import 'package:flutter/material.dart';
  32. import 'package:flutter/services.dart';
  33. import 'package:flutter_bugly/flutter_bugly.dart';
  34. import 'package:flutter_screenutil/flutter_screenutil.dart';
  35. //import 'package:flutter_bugly/flutter_bugly.dart';
  36. import 'package:location_permissions/location_permissions.dart' as lp;
  37. import 'package:package_info/package_info.dart';
  38. import 'package:permission_handler/permission_handler.dart';
  39. import 'package:oktoast/oktoast.dart';
  40. import 'package:provider/provider.dart';
  41. import 'package:shared_preferences/shared_preferences.dart';
  42. import 'home/IndexPage.dart';
  43. import 'generated/i18n.dart';
  44. import 'package:flutter_localizations/flutter_localizations.dart';
  45. import 'package:fluwx_no_pay/fluwx_no_pay.dart' as fluwx;
  46. import 'package:chat/data/UserData.dart' show UserData;
  47. import 'package:auto_orientation/auto_orientation.dart';
  48. import 'models/voucher_change.dart';
  49. //读取本地数据
  50. initLocalData() async {
  51. SharedPreferences prefs = await SharedPreferences.getInstance();
  52. var localUserId = prefs.getInt(Constants.LocalUserId);
  53. if (localUserId != null) {
  54. print('用户不为空');
  55. //设置用户基本信息
  56. UserData().basicInfo.userId = localUserId;
  57. String localUserData = await SPUtils.get(Constants.LocalUsrInfo);
  58. if (localUserData != null) {
  59. UserData().fromLocalJson(json.decode(localUserData));
  60. }
  61. //读取好友信息
  62. //读取聊天信息
  63. await ChatDataMgr().initMsg();
  64. //读取群信息
  65. await GroupInfoMgr().initLocalGroupList();
  66. }
  67. }
  68. void main() async {
  69. WidgetsFlutterBinding.ensureInitialized();
  70. LocalNotificationUtil.instance.initJPush();
  71. LocalNotificationUtil.instance.initLocalPush();
  72. await FileCacheMgr.initPathKey();
  73. await SqlUtil.init();
  74. await initLocalData();
  75. AutoOrientation.portraitUpMode();
  76. AMapLocationClient.setApiKey("3f4c9fca5f513ac0be361e92d8586ff3");
  77. AMapLocationClient.startup(new AMapLocationOption(
  78. desiredAccuracy: CLLocationAccuracy.kCLLocationAccuracyHundredMeters));
  79. setStatusBar();
  80. FlutterBugly.init(androidAppId: "d2a8d2c6a0", iOSAppId: "f0ad7340d0");
  81. FlutterBugly.postCatchedException(() {
  82. runApp(MyApp());
  83. }, debugUpload: true);
  84. // runApp(RestartWidget(
  85. // child: MyApp(),
  86. // ));
  87. }
  88. void setCustomErrorPage(BuildContext context) {
  89. ErrorWidget.builder = (FlutterErrorDetails flutterErrorDetails) {
  90. print(flutterErrorDetails.toString());
  91. return Scaffold(
  92. body: Center(
  93. child: Column(
  94. children: <Widget>[
  95. Container(
  96. margin: EdgeInsets.only(
  97. top: ScreenUtil.instance.setHeight(180),
  98. bottom: ScreenUtil.instance.setHeight(49)),
  99. child: Image.asset(
  100. 'assets/images/net_error.png',
  101. width: ScreenUtil.instance.setWidth(150),
  102. ),
  103. ),
  104. Container(
  105. margin: EdgeInsets.only(top: ScreenUtil().setHeight(50)),
  106. child: Text(
  107. I18n.of(LoadingManage.context).server_error_tips,
  108. style: TextStyle(color: Color(0xFF8F8E8E), fontSize: 18),
  109. ),
  110. ),
  111. ],
  112. )),
  113. );
  114. };
  115. }
  116. Map<String, int> language = {
  117. 'en_US': LanguageType.English,
  118. 'en_CN': LanguageType.English,
  119. 'vi_VN': LanguageType.Vietnamese,
  120. 'vi_CN': LanguageType.Vietnamese,
  121. 'vi_US': LanguageType.Vietnamese,
  122. 'zh_Hant_CN': LanguageType.TraditionalChinese,
  123. 'zh_TW': LanguageType.TraditionalChinese,
  124. 'zh_HK': LanguageType.TraditionalChinese,
  125. 'zh_Hant_MO': LanguageType.TraditionalChinese,
  126. 'zh_Hant_US': LanguageType.TraditionalChinese,
  127. 'zh_Hans_CN': LanguageType.SimplifiedChinese,
  128. 'zh_Hans_US': LanguageType.SimplifiedChinese,
  129. 'zh_CN': LanguageType.SimplifiedChinese,
  130. 'ko_KR': LanguageType.Korean,
  131. 'ko_KP': LanguageType.Korean,
  132. 'ko_Kore_CN': LanguageType.Korean,
  133. 'ko_Kore_US': LanguageType.Korean,
  134. 'ko_CN': LanguageType.Korean,
  135. 'ja_JP': LanguageType.Japanese,
  136. 'ja_US': LanguageType.Japanese,
  137. 'ja_CN': LanguageType.Japanese,
  138. };
  139. //全局去掉水波纹
  140. class NoSplashFactory extends InteractiveInkFeatureFactory {
  141. const NoSplashFactory();
  142. InteractiveInkFeature create({
  143. @required MaterialInkController controller,
  144. @required RenderBox referenceBox,
  145. @required Offset position,
  146. @required Color color,
  147. TextDirection textDirection,
  148. bool containedInkWell: false,
  149. RectCallback rectCallback,
  150. BorderRadius borderRadius,
  151. ShapeBorder customBorder,
  152. double radius,
  153. VoidCallback onRemoved,
  154. }) {
  155. return new NoSplash(
  156. controller: controller,
  157. referenceBox: referenceBox,
  158. color: color,
  159. onRemoved: onRemoved,
  160. );
  161. }
  162. }
  163. class NoSplash extends InteractiveInkFeature {
  164. NoSplash({
  165. @required MaterialInkController controller,
  166. @required RenderBox referenceBox,
  167. Color color,
  168. VoidCallback onRemoved,
  169. }) : assert(controller != null),
  170. assert(referenceBox != null),
  171. super(
  172. controller: controller,
  173. referenceBox: referenceBox,
  174. onRemoved: onRemoved) {
  175. controller.addInkFeature(this);
  176. }
  177. @override
  178. void paintFeature(Canvas canvas, Matrix4 transform) {}
  179. }
  180. class FallbackCupertinoLocalisationsDelegate
  181. extends LocalizationsDelegate<CupertinoLocalizations> {
  182. const FallbackCupertinoLocalisationsDelegate();
  183. @override
  184. bool isSupported(Locale locale) => true;
  185. @override
  186. Future<CupertinoLocalizations> load(Locale locale) =>
  187. DefaultCupertinoLocalizations.load(locale);
  188. @override
  189. bool shouldReload(FallbackCupertinoLocalisationsDelegate old) => false;
  190. }
  191. class MyApp extends StatefulWidget {
  192. MyApp({Key key}) : super(key: key);
  193. _MyAppState createState() => _MyAppState();
  194. }
  195. final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
  196. class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  197. final i18n = I18n.delegate;
  198. RefNameProvider _refNameProvider;
  199. bool isOpen = true;
  200. @override
  201. void initState() {
  202. super.initState();
  203. setCustomErrorPage(context);
  204. isAvailableAppleSignIn();
  205. Screen.initFactor();
  206. initVersionName();
  207. askLocationPermission();
  208. MsgHandler.context = context;
  209. I18n.onLocaleChanged = onLocaleChange;
  210. WidgetsBinding.instance.addObserver(this);
  211. ReceiveShareFile.init();
  212. ScreenShot.getFileStream();
  213. }
  214. isAvailableAppleSignIn() async {
  215. isOpen = (await SPUtils.getBool(Constants.Splash_OPENED)) ?? false;
  216. OtherLogin.isAvailableForAppleSignIn = await AppleSignIn.isAvailable();
  217. }
  218. @override
  219. void didChangeDependencies() {
  220. super.didChangeDependencies();
  221. if (_refNameProvider == null) {
  222. _refNameProvider = RefNameProvider();
  223. }
  224. }
  225. initVersionName() async {
  226. PackageInfo packageInfo = await PackageInfo.fromPlatform();
  227. Constants.versionName = packageInfo.version;
  228. Constants.packageName = packageInfo.packageName;
  229. }
  230. @override
  231. void dispose() {
  232. //positionStream?.cancel();
  233. WidgetsBinding.instance.removeObserver(this);
  234. // LocalNotificationUtil.instance.dispose();
  235. super.dispose();
  236. }
  237. @override
  238. void didChangeAppLifecycleState(AppLifecycleState state) async {
  239. print("--" + state.toString());
  240. switch (state) {
  241. case AppLifecycleState.inactive: // 处于这种状态的应用程序应该假设它们可能在任何时候暂停。
  242. break;
  243. case AppLifecycleState.resumed: // 应用程序可见,前台
  244. setStatusBar();
  245. print('切换到前台');
  246. //检测用户是否开启定位权限
  247. MessageMgr().emit('test_Permission');
  248. NetWork().checkConnect();
  249. MessageMgr().emit(MessageMgr.REFRESH_PUSH_PERMISSION);
  250. LocalNotificationUtil.isBackground = false;
  251. LocalNotificationUtil.instance.cleanAllNotifications();
  252. if (UserData().isBannerStatus) {
  253. UserData().isBannerStatus = false;
  254. MessageMgr().emit('refresh_money');
  255. }
  256. if (MsgHandler.audioChatRequestFriendId > 0) {
  257. MessageMgr().emit(
  258. 'Receive AudioChat Request', MsgHandler.audioChatRequestFriendId);
  259. }
  260. break;
  261. case AppLifecycleState.paused: // 应用程序不可见,后台
  262. print('切换到后台');
  263. LocalNotificationUtil.isBackground = true;
  264. SoundUtils.instance.pause();
  265. if(Platform.isIOS)NetWork().reallyClose(); ///iOS切后台关闭socket不然会闪退
  266. break;
  267. // case AppLifecycleState.suspending: // 申请将暂时暂停
  268. // print('程序挂起');
  269. // break;
  270. case AppLifecycleState.detached: // 申请将暂时暂停
  271. // print('程序挂起');
  272. break;
  273. }
  274. }
  275. void onLocaleChange(Locale locale) {
  276. final String lang = locale != null ? locale.toString() : "";
  277. print('#### onLocaleChange $lang');
  278. setState(() {
  279. I18n.locale = locale;
  280. });
  281. }
  282. setDisableScreenshots() async {
  283. print('Platform.isAndroid ${Platform.isAndroid}');
  284. if (Platform.isAndroid) {
  285. await FlutterWindowManager.addFlags(FlutterWindowManager.FLAG_SECURE);
  286. }
  287. }
  288. @override
  289. Widget build(BuildContext context) {
  290. fluwx.registerWxApi(
  291. appId: Constants.AppId,
  292. universalLink: "https://www.xxx.com/iosuniversallink/");
  293. return OKToast(
  294. child: MultiProvider(
  295. providers: [
  296. ChangeNotifierProvider(create: (_) => GiftSelectProvider()),
  297. ChangeNotifierProvider(create: (_) => MoneyChangeProvider()),
  298. ChangeNotifierProvider(create: (_) => _refNameProvider),
  299. ChangeNotifierProvider(create: (_) => VoucherChangeProvider()),
  300. ],
  301. child: MaterialApp(
  302. theme: ThemeData(
  303. platform: TargetPlatform.iOS,
  304. highlightColor: Colors.transparent,
  305. splashFactory: const NoSplashFactory(),
  306. toggleableActiveColor: Constants.BlueTextColor,
  307. scaffoldBackgroundColor: Constants.GreyBackgroundColor,
  308. accentColor: Constants.BlueTextColor,
  309. indicatorColor: Constants.BlueTextColor,
  310. tabBarTheme: TabBarTheme(
  311. indicatorSize: TabBarIndicatorSize.label,
  312. labelColor: Constants.BlueTextColor,
  313. unselectedLabelColor: Constants.GreyTextColor,
  314. labelPadding: EdgeInsets.only(bottom: 5, left: 15, right: 15),
  315. labelStyle:
  316. TextStyle(fontWeight: FontWeight.w600, fontSize: 15),
  317. unselectedLabelStyle:
  318. TextStyle(fontWeight: FontWeight.w500, fontSize: 15),
  319. ),
  320. appBarTheme: AppBarTheme(
  321. elevation: 0,
  322. brightness: Brightness.light,
  323. color: Colors.white,
  324. iconTheme: IconThemeData(color: Colors.black),
  325. actionsIconTheme: IconThemeData(color: Colors.black),
  326. textTheme: TextTheme(
  327. title: TextStyle(
  328. color: Constants.BlackTextColor, fontSize: 20))),
  329. primaryColor: Constants.BlueTextColor,
  330. inputDecorationTheme: InputDecorationTheme(
  331. labelStyle: TextStyle(
  332. fontSize: 13, color: Constants.BlackTextColor),
  333. border: InputBorder.none,
  334. contentPadding: EdgeInsets.all(10),
  335. hintStyle: TextStyle(
  336. fontSize: 11,
  337. color: Color.fromARGB(255, 192, 191, 191))),
  338. ),
  339. localizationsDelegates: [
  340. i18n,
  341. GlobalMaterialLocalizations.delegate,
  342. GlobalWidgetsLocalizations.delegate,
  343. GlobalCupertinoLocalizations.delegate, // <-- needed for iOS
  344. const FallbackCupertinoLocalisationsDelegate()
  345. ],
  346. supportedLocales: i18n.supportedLocales,
  347. title: 'Chat',
  348. onGenerateTitle: (context) {
  349. // 此处
  350. return 'Hibok';
  351. },
  352. navigatorKey: navigatorKey,
  353. routes: <String, WidgetBuilder>{
  354. '/main': (BuildContext context) => HomeMain(),
  355. },
  356. home: Builder(builder: (context) {
  357. return goIndex();
  358. }),
  359. //home: IndexPage(),
  360. localeResolutionCallback: (deviceLocale, supportedLocales) {
  361. if (deviceLocale != null) {
  362. final String lang =
  363. deviceLocale != null ? deviceLocale.toString() : "";
  364. print('#### fl: $lang');
  365. //设置设备语言
  366. if (language.containsKey(deviceLocale.toString()))
  367. UserData().deviceLanguage =
  368. language[deviceLocale.toString()];
  369. getPosition(deviceLocale);
  370. }
  371. return deviceLocale;
  372. },
  373. )));
  374. }
  375. goIndex() {
  376. LoadingManage.context = navigatorKey.currentState.overlay.context;
  377. if (!isOpen) {
  378. return SplashPage();
  379. } else {
  380. return IndexPage();
  381. }
  382. }
  383. askLocationPermission() async {
  384. lp.PermissionStatus status =
  385. await lp.LocationPermissions().checkPermissionStatus();
  386. print('定位权限 $status');
  387. final PermissionStatus addStatus = await PermissionHandler()
  388. .checkPermissionStatus(PermissionGroup.contacts);
  389. print('通讯录权限 $addStatus');
  390. List<PermissionGroup> permissionList = [];
  391. if (status == lp.PermissionStatus.granted) {
  392. UserData().hasLocationPermission = true;
  393. } else {
  394. permissionList.add(PermissionGroup.locationWhenInUse);
  395. }
  396. if (addStatus == PermissionStatus.granted) {
  397. setContact();
  398. } else {
  399. if (Platform.isAndroid) {
  400. // ///ios隐藏
  401. permissionList.add(PermissionGroup.contacts);
  402. }
  403. }
  404. print(permissionList);
  405. if (permissionList.length != 0) {
  406. Map<PermissionGroup, PermissionStatus> permissionRequestResult =
  407. await PermissionHandler().requestPermissions(permissionList);
  408. var status = permissionRequestResult[PermissionGroup.locationWhenInUse];
  409. var addStatus = permissionRequestResult[PermissionGroup.contacts];
  410. if (status == PermissionStatus.granted) {
  411. UserData().hasLocationPermission = true;
  412. }
  413. if (addStatus == PermissionStatus.granted) {
  414. setContact();
  415. }
  416. }
  417. MessageMgr().emit('test_Permission');
  418. }
  419. setContact() async {
  420. final EasyContactPicker _contactPicker = new EasyContactPicker();
  421. List<Contact> _list = await _contactPicker.selectContacts();
  422. UserData().contactList.clear();
  423. _list.forEach((contack) {
  424. UserData()
  425. .contactList
  426. .add({'PhoneNumber': contack.phoneNumber, 'Name': contack.fullName});
  427. });
  428. MessageMgr().emit('PostContact');
  429. }
  430. void getPosition(deviceLocale) async {
  431. SharedPreferences prefs = await SharedPreferences.getInstance();
  432. var localLanguage = prefs.getInt(Constants.Language);
  433. print('localLanguage$localLanguage');
  434. if (localLanguage == null) {
  435. if (language.containsKey(deviceLocale.toString()))
  436. UserData().language = language[deviceLocale.toString()];
  437. } else {
  438. UserData().language = localLanguage;
  439. }
  440. WebData().getAllData();
  441. UserData().getCurrentPosition();
  442. }
  443. }