main.dart 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'package:dart_ping/dart_ping.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter/services.dart';
  6. import 'package:smartledz_wifi_test/plugin/wifi_plugin.dart';
  7. import 'package:flutter_screenutil/flutter_screenutil.dart';
  8. import 'package:smartledz_wifi_test/models/wifi_model.dart';
  9. import 'package:smartledz_wifi_test/utils/modal.dart';
  10. import 'package:smartledz_wifi_test/widgets/button_for_block.dart';
  11. import 'package:smartledz_wifi_test/widgets/wifi_item.dart';
  12. void main() {
  13. runApp(const MyApp());
  14. }
  15. class MyApp extends StatelessWidget {
  16. const MyApp({super.key});
  17. @override
  18. Widget build(BuildContext context) {
  19. return ScreenUtilInit(
  20. builder: (BuildContext context, Widget? child) {
  21. return MaterialApp(
  22. title: 'FX430 WIFI测试',
  23. theme: ThemeData(
  24. primarySwatch: Colors.blue,
  25. ),
  26. home: Scaffold(
  27. body: Column(
  28. children: [
  29. Container(
  30. color: Colors.blue,
  31. alignment: Alignment.center,
  32. child: SafeArea(
  33. left: false,
  34. right: false,
  35. bottom: false,
  36. child: Container(
  37. alignment: Alignment.center,
  38. height: 50.h,
  39. child: Text("FX430 WIFI测试", style: TextStyle(color: Colors.white, fontSize: 20.sp)),
  40. ),
  41. ),
  42. ),
  43. const Expanded(
  44. child: WifiList(),
  45. )
  46. ],
  47. ),
  48. ),
  49. );
  50. },
  51. );
  52. }
  53. }
  54. class WifiList extends StatefulWidget {
  55. const WifiList({Key? key}) : super(key: key);
  56. @override
  57. State<WifiList> createState() => _WifiListState();
  58. }
  59. class _WifiListState extends State<WifiList> {
  60. final List<WifiModel> _wifiList = []; // 扫描的wifi列表
  61. final List<String> _selectWifiList = []; // 已选择的wifi的bssid标识列表
  62. void Function()? _connectCallback; // 连接成功回调
  63. void Function()? _disconnectCallback; // 断开连接回调
  64. @override
  65. void initState() {
  66. super.initState();
  67. var eventChannel = const EventChannel('native_event_channel');
  68. eventChannel.receiveBroadcastStream().listen((dataStr) {
  69. Map jsonArr = jsonDecode(dataStr);
  70. debugPrint("收到通知事件 ---> $jsonArr");
  71. switch(jsonArr["cmd"]){
  72. case "scanResult": // 扫描
  73. setState(() {
  74. for (var element in _wifiList) { // 已存在则跳过
  75. if(element.bssid == jsonArr["bssid"]) return;
  76. }
  77. _wifiList.add(WifiModel(
  78. ssid: jsonArr["ssid"],
  79. bssid: jsonArr["bssid"],
  80. rssi: int.parse(jsonArr["level"])
  81. ));
  82. });
  83. break;
  84. case "scanComplete": // 扫描完成
  85. setState(() { // 检查已选列表的wifi是否真实存在
  86. _selectWifiList.removeWhere((bssid){
  87. for(WifiModel wifiModel in _wifiList){ // 已存在则不删除
  88. if(wifiModel.bssid == bssid) return false;
  89. }
  90. return true;
  91. });
  92. });
  93. break;
  94. case "connected": // 连接成功
  95. _connectCallback?.call();
  96. break;
  97. case "disconnect": // 断开连接
  98. debugPrint("断开连接回调 _____> ");
  99. _disconnectCallback?.call();
  100. break;
  101. }
  102. });
  103. startScanWifi();
  104. }
  105. // 扫描wifi
  106. void startScanWifi([void Function()? callback]){
  107. _wifiList.clear();
  108. WiFiPlugin.startScan();
  109. Future.delayed(const Duration(seconds: 3), (){
  110. callback?.call();
  111. });
  112. }
  113. // 开始测试
  114. void startTest(){
  115. if(_wifiList.isEmpty){
  116. Modal.toast(msg: "wifi列表为空,无法测试");
  117. return;
  118. }
  119. if(_selectWifiList.isNotEmpty){ // 有选中的wifi,则只处理选中的wifi
  120. eachTestWifiList(true);
  121. return;
  122. }
  123. // 处理全部wifi
  124. eachTestWifiList(false);
  125. }
  126. // 循环测试wifi列表
  127. void eachTestWifiList(bool isSelect, [int index=0]){
  128. debugPrint("$isSelect $index");
  129. int wifiIndex = index;
  130. if(isSelect == true){ // 处理选中设备
  131. if(index > _selectWifiList.length){ // 处理完成
  132. return;
  133. }
  134. for(int i=0; i<_wifiList.length; i++){
  135. if(_wifiList[i].bssid == _selectWifiList[index]){
  136. wifiIndex = i; // 获取选中设备在wifi列表中的索引值
  137. break;
  138. }
  139. }
  140. }else{
  141. if(index > _wifiList.length){ // 处理完成
  142. return;
  143. }
  144. }
  145. WifiModel wifiModel = _wifiList[wifiIndex];
  146. setState(()=>_wifiList[wifiIndex].result="正在连接");
  147. debugPrint("开始连接wifi ssid --> ${wifiModel.ssid} bssid --> ${wifiModel.bssid}");
  148. var timer = Timer(const Duration(seconds: 5), (){ // 连接超时检测
  149. _connectCallback = null;
  150. setState(()=>_wifiList[wifiIndex].result="连接失败");
  151. eachTestWifiList(isSelect, index+1); // 开始测试下一个设备
  152. });
  153. _connectCallback = (){
  154. timer.cancel(); // 销毁连接超时检测定时器
  155. debugPrint("wifi ---> 连接成功");
  156. setState(()=>_wifiList[wifiIndex].result="正在测试");
  157. final ping = Ping('192.168.16.254', count: 3);
  158. int? ttl; // ping检测结果
  159. ping.stream.listen((event) {
  160. debugPrint("ping --> $event");
  161. if(event.response?.ttl != null){
  162. ttl = event.response!.ttl;
  163. }
  164. });
  165. Future.delayed(const Duration(seconds: 3), (){
  166. if(ttl != null){
  167. setState(()=>_wifiList[wifiIndex].result="测试通过");
  168. }else{
  169. setState(()=>_wifiList[wifiIndex].result="未通过");
  170. }
  171. _disconnectCallback = (){ // 断开成功的回调
  172. eachTestWifiList(isSelect, index+1); // 开始测试下一个设备
  173. };
  174. WiFiPlugin.disconnect();
  175. });
  176. };
  177. WiFiPlugin.connect(wifiModel.ssid, wifiModel.bssid, "12345678");
  178. }
  179. @override
  180. Widget build(BuildContext context) {
  181. return Column(
  182. children: [
  183. Expanded(
  184. child: ListView(
  185. padding: EdgeInsets.zero,
  186. children: List.generate(_wifiList.length, (index){
  187. WifiModel wifi = _wifiList[index];
  188. return WifiItem(
  189. wifiModel: wifi, // wifi模型
  190. active: _selectWifiList.contains(wifi.bssid), // 是否选中状态
  191. onTap: (WifiModel wifiModel){ // 列表点击事件
  192. setState(() {
  193. if(_selectWifiList.contains(wifi.bssid)){ // 已选中,则取消选中
  194. _selectWifiList.remove(wifi.bssid);
  195. }else{
  196. _selectWifiList.add(wifi.bssid);
  197. }
  198. });
  199. },
  200. );
  201. }),
  202. ),
  203. ),
  204. Row(
  205. children: [
  206. ButtonForBlock(
  207. title: "刷新列表",
  208. fontSize: 20.sp,
  209. radius: 0,
  210. bgColor: const Color(0xFFFFAA00),
  211. activeBgColor: const Color(0xFFAA8800),
  212. width: MediaQuery.of(context).size.width/2,
  213. height: 55.sp,
  214. onTap: (){
  215. Modal.openLoading(context: context, tip: "正在扫描wifi");
  216. startScanWifi((){
  217. Navigator.pop(context);
  218. });
  219. },
  220. ),
  221. ButtonForBlock(
  222. title: "开始测试",
  223. fontSize: 20.sp,
  224. radius: 0,
  225. width: MediaQuery.of(context).size.width/2,
  226. height: 55.sp,
  227. onTap: startTest,
  228. )
  229. ],
  230. )
  231. ],
  232. );
  233. }
  234. }