Как я сделал сканер под iOS и Android для диагностики Wi-Fi-сети

Программирование 10 июнь 2026 admin

Как я сделал сканер под iOS и Android для диагностики Wi-Fi-сети

Когда в офисе начались проблемы с Wi-Fi, стандартные утилиты показывали только уровень сигнала. Нужно было понять, какие каналы загружены, где помехи, и как роутер распределяет нагрузку. Решение написать собственный сканер под iOS и Android казалось очевидным: берём Flutter, одну кодовую базу, и получаем приложение сразу для двух платформ. В этой статье я расскажу, как собрал данные о точках доступа, обошёл ограничения мобильных ОС и сделал удобный инструмент для диагностики. Если вы сталкивались с нестабильным Wi-Fi или хотите глубже понять, как работают мобильные сетевые утилиты — милости прошу.

Выбор инструментов и архитектура

Для кросс-платформенной разработки взял Flutter. Для сканирования Wi-Fi пришлось использовать два разныx пакета: flutter_wifi_scan для Android и wifi_info_plugin для iOS. Android даёт полный доступ к списку точек доступа с BSSID, SSID, уровнем сигнала и частотой. iOS же с iOS 9 ограничивает фоновое сканирование — приложение может получить информацию только о текущей сети. Пришлось добавить отдельный поток для периодического опроса и агрегации данных.

Архитектура модульная: отдельный слой для сбора данных (платформенные адаптеры), слой обработки (фильтрация, усреднение RSSI) и слой визуализации (графики на CustomPainter). Для хранения истории использовал SQLite через пакет sqflite.

Важное замечание: на Android нужно добавить разрешения ACCESS_FINE_LOCATION и ACCESS_WIFI_STATE, а на iOS — Capability Access WiFi Information. Без них сканирование не работает.

Сбор данных о сети на Android

На Android самый простой путь — использовать WifiManager через MethodChannel. Вот пример кода для запуска сканирования и получения результатов:

import 'package:flutter/services.dart';

class AndroidWifiScanner {
  static const platform = MethodChannel('wifi_scanner');

  Future

На стороне Android (Kotlin) обрабатываем запрос:

override fun onMethodCall(call: MethodCall, result: Result) {
  if (call.method == "startScan") {
    val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
    val receiver = object : BroadcastReceiver() {
      override fun onReceive(context: Context, intent: Intent) {
        val scanResults = wifiManager.scanResults
        val list = scanResults.map { scanResult ->
          mapOf(
            "ssid" to scanResult.SSID,
            "bssid" to scanResult.BSSID,
            "level" to scanResult.level,
            "frequency" to scanResult.frequency
          )
        }
        result.success(list)
        context.unregisterReceiver(this)
      }
    }
    context.registerReceiver(receiver, IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))
    wifiManager.startScan()
  }
}

Сбор данных на iOS: ограничения и обход

iOS не даёт полного сканирования, но можно получить информацию о текущей точке доступа через NEHotspotNetwork. Для этого используем wifi_info_plugin:

import 'package:wifi_info_plugin/wifi_info_plugin.dart';

class IosWifiScanner {
  Future<Map<String, dynamic>> getCurrentWifiInfo() async {
    try {
      var wifiInfo = await WifiInfoPlugin.wifiInfo;
      return {
        'ssid': wifiInfo.ssid ?? '',
        'bssid': wifiInfo.bssid ?? '',
        'level': wifiInfo.level ?? 0,
      };
    } catch (e) {
      print('Ошибка получения информации о Wi-Fi: $e');
      return {};
    }
  }
}

Чтобы хоть как-то оценить обстановку, пришлось добавить механизм перемещения пользователя и логирования уровня сигнала в разных точках. По сути, iOS-версия стала «следопытом», а Android — полноценным сканером.

Сравнение возможностей Android и iOS

ПараметрAndroidiOS
Доступ к списку точек доступаДа (полный)Нет (только текущая)
BSSIDДаДа (для текущей)
Уровень сигнала (RSSI)ДаДа (для текущей)
Частота/каналДаНет
Фоновое сканированиеДаТолько в foreground
РазрешенияACCESS_FINE_LOCATION, ACCESS_WIFI_STATEAccess WiFi Information + Location

Визуализация и анализ

Данные выводились в виде линии уровня сигнала по времени и карты точек доступа с цветовой индикацией (зелёный — сильный сигнал, красный — слабый). Для отрисовки графиков использовал CustomPainter. Также реализовал фильтр по SSID и сортировку по уровню сигнала. На Android можно было построить тепловую карту каналов — это позволило выявить перегруженный канал 6 в офисе.

Совет: для Android используйте метод getScanResults только после того, как сканирование завершилось. Иначе получите пустой список. Я повесил BroadcastReceiver на SCAN_RESULTS_AVAILABLE_ACTION.

Практические советы и результаты

  • Для минимизации нагрузки на батарею делайте паузу между сканированиями не менее 10 секунд.
  • На iOS не пытайтесь получить список сетей — только текущую. Смиритесь.
  • Используйте SQLite для хранения истории — это позволяет увидеть динамику изменения сигнала.
  • Добавьте экспорт данных в CSV, чтобы передать сисадмину.

Личное наблюдение автора: когда я запустил сканер на Android в офисе, сразу увидел, что на канале 6 работают 8 точек доступа — очевидная причина деградации. Перенос сети на канал 11 решил проблему. iOS-версия оказалась менее полезной, но её можно использовать для приёмочного тестирования зоны покрытия.

Заключение

Создать Wi-Fi сканер под обе платформы реально, но придётся учитывать ограничения iOS. Flutter позволил переиспользовать 80% кода, а платформенные адаптеры сделали остальное. Если нужно простое приложение для диагностики — берите готовые библиотеки, но если хотите глубже разобраться в сетевом стеке — пишите сами.

Редакция «ИТ Фишки»
Качественные материалы о софте, технологиях и гаджетах
Ссылка на материал
Поделиться:
Похожие публикации
Комментарии (0)

© Copyright © 2026. Все права защищены.