Android: как контролировать уровень сигнала WiFi

Я получаю уведомления, когда изменяется сила сигнала. Я попытался создать следующий метод и называть его в onCreate():

private void initializeWiFiListener(){
    Log.i(TAG, "executing initializeWiFiListener");

    String connectivity_context = Context.WIFI_SERVICE;
    final WifiManager wifi = (WifiManager)getSystemService(connectivity_context);

    if(!wifi.isWifiEnabled()){
        if(wifi.getWifiState() != WifiManager.WIFI_STATE_ENABLING){
            wifi.setWifiEnabled(true);
        }
    }

    registerReceiver(new BroadcastReceiver(){

        @Override
        public void onReceive(Context context, Intent intent) {
            WifiInfo info = wifi.getConnectionInfo();
            //TODO: implement methods for action handling
        }

    }, new IntentFilter(WifiManager.RSSI_CHANGED_ACTION));
}

Я был бы признателен, если бы кто-нибудь мог проверить, правильно ли написан метод. Я попытался запустить приложение, но не получил никаких уведомлений и не уверен, связано ли это с тем, что уровень сигнала может быть постоянным в том месте, где я запускаю отладку, или потому что чего-то не хватает.

Спасибо!

Ответ 1

Во-первых, убедитесь, что в манифесте есть <uses-permission> для ACCESS_WIFI_STATE.

Во-вторых, я не уверен в уведомлениях для одного соединения, но чтобы получать уведомления обо всем, что видит радио, вы можете запустить сканирование:

wifi.startScan();

Затем, когда я получил успешные результаты, я использовал WifiManager.SCAN_RESULTS_AVAILABLE_ACTION в IntentFilter.

Затем в приемнике я использую getScanResults() из объекта WifiManager, который также содержит уровень сигнала.

Чтобы остановить его таким образом, вы просто вызываете unregisterRecever() (так что вы захотите сохранить его для ссылок). Я не тестировал себя, чтобы проверить, можно ли изменить код сканирования, чтобы просто проверить текущее соединение, но я знаю, что у меня много результатов - сигналы Wi-Fi меняются часто и быстро. Я полагаю, что для мониторинга одного соединения вы также можете просто фильтровать результаты сканирования и искать тот, к которому подключено устройство.

Надеюсь, это немного поможет.

Ответ 2

Просто отказаться от моего решения:

в моем приложении у меня

@Override
protected void onResume() {
    super.onResume();
    networkStateReceiver = new NetworkStateReceiver(this);
    this.registerReceiver(networkStateReceiver, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));
    this.registerReceiver(networkStateReceiver, new IntentFilter("android.net.wifi.SCAN_RESULTS"));
    networkStateReceiver.registerListener(this);
}

И onReceive в моем приемнике выглядит так:

@Override
public void onReceive(Context context, Intent intent) {
    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
    if (networkInfo != null && networkInfo.isConnectedOrConnecting()) {
        switch (networkInfo.getType()) {
            case ConnectivityManager.TYPE_ETHERNET:
                this.networkStateMessage = new NetworkStateMessage(networkInfo);
                break;
            case ConnectivityManager.TYPE_WIFI:
                this.networkStateMessage = new NetworkStateMessage(networkInfo, wifiManager.getConnectionInfo());
                worker.schedule(new Runnable() {
                    @Override
                    public void run() { wifiManager.startScan(); }
                }, 5, TimeUnit.SECONDS);
                break;
            default:
                this.networkStateMessage = null;
                break;
        }
    }
    notifyStateToAll(this.networkStateMessage);
}

Идея заключается в startScan() только каждые 5 секунд, если Wi-Fi является активной сетью.