Как я сделал сканер под iOS и Android для диагностики Wi-Fi-сети
Почему ваш Wi-Fi тормозит: как я написал сканер сети под iOS и Android (и что из этого вышло)
В нашем офисе Wi-Fi работал из рук вон плохо. Стандартные утилиты показывали только уровень сигнала — этого было недостаточно. Нужно было понять, какие каналы загружены, где источник помех и как роутер распределяет нагрузку. Решение написать собственный сканер под iOS и Android казалось очевидным: берём Flutter, одну кодовую базу — и получаем приложение сразу для двух платформ. Расскажу, как я собирал данные о точках доступа, обходил ограничения мобильных ОС и что в итоге получилось.
Как Flutter помогает (и мешает) писать под две платформы
Для кросс-платформенной разработки взял Flutter. Он позволяет переиспользовать около 80% кода, но платформенные адаптеры всё равно приходится писать отдельно. Для сканирования Wi-Fi использовал два пакета: flutter_wifi_scan для Android и wifi_info_plugin для iOS. Android даёт полный доступ к списку точек с BSSID, SSID, уровнем сигнала и частотой. iOS же, начиная с версии 9, ограничивает фоновое сканирование — приложение может получить информацию только о текущей сети. Пришлось добавить отдельный поток для периодического опроса и агрегации данных. Архитектура модульная: слой сбора данных (платформенные адаптеры), слой обработки (фильтрация, усреднение RSSI) и слой визуализации (графики на CustomPainter). Для хранения истории использовал SQLite через пакет sqflite.
Важное замечание: на Android нужны разрешения ACCESS_FINE_LOCATION и ACCESS_WIFI_STATE, на iOS — Capability Access WiFi Information. Без них сканирование не работает. Причём на Android 10+ ACCESS_FINE_LOCATION требуется даже если вам не нужны координаты — это особенность системы.
Android: полный доступ к эфиру
На Android самый простой путь — использовать WifiManager через MethodChannel. Процесс выглядит так: отправляешь команду на нативной стороне, запускаешь сканирование, вешаешь BroadcastReceiver на событие SCAN_RESULTS_AVAILABLE_ACTION, и после завершения получаешь список ScanResult. В каждом объекте есть SSID, BSSID, уровень сигнала в dBm (RSSI) и частота. Частоту легко конвертировать в номер канала: 2.4 ГГц — каналы 1–13, 5 ГГц — более широкий диапазон.
Микро-инструкция: Как собрать данные о Wi-Fi на Android за 5 шагов
- Добавьте в манифест разрешения ACCESS_FINE_LOCATION и ACCESS_WIFI_STATE.
- Создайте MethodChannel в Flutter и вызовите метод startScan.
- На стороне Kotlin зарегистрируйте BroadcastReceiver на SCAN_RESULTS_AVAILABLE_ACTION.
- После получения результатов передайте их обратно во Flutter через result.success.
- В Dart обработайте список и обновите UI.
Личное наблюдение автора: когда я запустил сканер на Android в офисе, сразу увидел, что на канале 6 работают 8 точек доступа — очевидная причина деградации. Перенёс сеть на канал 11, и скорость выросла в два раза. Без приложения я бы этого не заметил.
iOS: почему Apple не даёт вам видеть чужие сети
iOS — это квест. Вы не можете получить список окружающих точек доступа. Только текущую сеть. Через NEHotspotNetwork доступны SSID, BSSID и уровень сигнала, но — только если устройство уже подключено к этой сети. Более того, чтобы получить эти данные, нужно включить Capability Access WiFi Information и запросить разрешение на геолокацию. Даже так — никаких соседних сетей. Для оценки обстановки пришлось добавить механизм перемещения пользователя и логирования уровня сигнала в разных точках. iOS-версия стала «следопытом»: она записывает показания по мере того, как вы ходите по помещению. Android же остался полноценным сканером.
Сравнение возможностей Android и iOS
| Параметр | Android | iOS |
|---|---|---|
| Доступ к списку точек доступа | Да (полный) | Нет (только текущая) |
| BSSID | Да | Да (для текущей) |
| Уровень сигнала (RSSI) | Да | Да (для текущей) |
| Частота / канал | Да | Нет |
| Фоновое сканирование | Да | Только в foreground |
| Разрешения | ACCESS_FINE_LOCATION + ACCESS_WIFI_STATE | Access WiFi Information + Location |
Что в итоге получилось и как этим пользоваться
Данные выводились в виде линии уровня сигнала по времени и карты точек доступа с цветовой индикацией (зелёный — сильный сигнал, красный — слабый). Для отрисовки графиков использовал CustomPainter. Реализовал фильтр по SSID и сортировку по уровню сигнала. На Android построил тепловую карту каналов — она показала перегруженный канал 6.
Практические советы, которые вынесу:
- Делайте паузу между сканированиями не менее 10 секунд — иначе батарея сядет за час.
- На iOS не пытайтесь получить список сетей — смиритесь. Только текущая точка доступа.
- Используйте SQLite для хранения истории — динамика изменения сигнала видна сразу.
- Добавьте экспорт данных в CSV — сисадмин скажет спасибо.
- Если нужен полноценный анализатор — берите Android. iOS подойдёт только для приёмочного тестирования зоны покрытия.
Совет: на Android вызывайте getScanResults только после того, как BroadcastReceiver подтвердил завершение сканирования. Иначе получите пустой список. Я наступил на эти грабли — потратил час на отладку.
Резюме от автора
Создать Wi-Fi сканер под обе платформы реально. Flutter экономит время, но ограничения iOS ломают всю картину. Если вам нужно понять, почему сеть тормозит, — напишите простой сканер под Android. На iOS лучше установите готовое приложение с ручным обходом помещений. Я считаю, что Apple намеренно ограничивает доступ к эфиру ради приватности — это правильно, но для диагностики неудобно. В итоге я получил инструмент, который спас офисный Wi-Fi. И вам советую не ждать чуда — берите код и делайте.












