bluetooth_reboot.dart 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_blue_plus/flutter_blue_plus.dart';
  3. import 'package:get/get.dart';
  4. import 'package:fis_common/logger/logger.dart';
  5. enum _RebootStep {
  6. ready,
  7. turnOff,
  8. turnOn,
  9. done,
  10. error,
  11. }
  12. final _stepDescMap = <_RebootStep, String>{
  13. _RebootStep.ready: "等待重启蓝牙",
  14. _RebootStep.turnOff: "正在关闭蓝牙",
  15. _RebootStep.turnOn: "正在打开蓝牙",
  16. _RebootStep.done: "重启蓝牙完成",
  17. };
  18. class BluetoothRebootDialog extends StatefulWidget {
  19. const BluetoothRebootDialog({super.key});
  20. static Future<String?> run() async {
  21. final result = await Get.dialog(
  22. const BluetoothRebootDialog(),
  23. barrierDismissible: false,
  24. );
  25. return result;
  26. }
  27. @override
  28. State<StatefulWidget> createState() => _BluetoothRebootDialogState();
  29. }
  30. class _BluetoothRebootDialogState extends State<BluetoothRebootDialog> {
  31. _RebootStep currStep = _RebootStep.ready;
  32. String? errorMessage;
  33. @override
  34. void initState() {
  35. super.initState();
  36. WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
  37. if (mounted) {
  38. doNext();
  39. }
  40. });
  41. }
  42. Future<void> doNext() async {
  43. bool ret = false;
  44. switch (currStep) {
  45. case _RebootStep.ready:
  46. ret = await turnOff();
  47. break;
  48. case _RebootStep.turnOff:
  49. ret = await turnOn();
  50. break;
  51. case _RebootStep.turnOn:
  52. ret = await reportDone();
  53. break;
  54. case _RebootStep.done:
  55. await Future.delayed(const Duration(milliseconds: 1500)); // 展示信息
  56. ret = false; // 完成并推出
  57. break;
  58. default:
  59. return;
  60. }
  61. if (ret) {
  62. setState(() {
  63. currStep = _RebootStep.values[currStep.index + 1];
  64. });
  65. // 继续下一步
  66. Future.delayed(const Duration(milliseconds: 500), doNext);
  67. } else {
  68. exit();
  69. }
  70. }
  71. /// 退出
  72. void exit() async {
  73. if (errorMessage != null) {
  74. setState(() {
  75. currStep = _RebootStep.error;
  76. });
  77. await Future.delayed(const Duration(milliseconds: 1500)); // 展示信息
  78. }
  79. Get.back(result: errorMessage);
  80. }
  81. Future<bool> turnOff() async {
  82. try {
  83. final isOn = await FlutterBluePlus.isOn;
  84. if (isOn) {
  85. await FlutterBluePlus.turnOff();
  86. }
  87. return true;
  88. } catch (e) {
  89. logger.e("BluetoothRebootDialog turn bluetooth off error", e);
  90. errorMessage = "关闭蓝牙失败";
  91. return false;
  92. }
  93. }
  94. Future<bool> turnOn() async {
  95. try {
  96. await FlutterBluePlus.turnOn();
  97. return true;
  98. } catch (e) {
  99. logger.e("BluetoothRebootDialog turn bluetooth on error", e);
  100. errorMessage = "启动蓝牙失败";
  101. return false;
  102. }
  103. }
  104. Future<bool> reportDone() async {
  105. await Future.delayed(const Duration(milliseconds: 200));
  106. return true;
  107. }
  108. @override
  109. Widget build(BuildContext context) {
  110. final body = buildBody(context);
  111. return AlertDialog(
  112. contentPadding: const EdgeInsets.symmetric(horizontal: 32, vertical: 28),
  113. content: body,
  114. );
  115. }
  116. Widget buildBody(BuildContext context) {
  117. final showLoading = currStep.index < _RebootStep.done.index;
  118. final message = errorMessage ?? _stepDescMap[currStep]!;
  119. List<Widget> children = [];
  120. children.add(
  121. Text(
  122. message,
  123. style: const TextStyle(fontSize: 20),
  124. ),
  125. );
  126. if (showLoading) {
  127. children.add(const SizedBox(width: 8));
  128. children.add(
  129. const SizedBox(
  130. width: 20,
  131. height: 20,
  132. child: CircularProgressIndicator(),
  133. ),
  134. );
  135. }
  136. return Row(
  137. mainAxisAlignment: MainAxisAlignment.center,
  138. children: children,
  139. );
  140. }
  141. }