main.dart 7.3 KB

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