2

Вот мой код:Android Wifi Scan - BroadcastReceiver для SCAN_RESULTS_AVAILABLE_ACTION не вызывался

public class FloatWifiManager implements IWifiManager { 

    private WifiManager wifiManager; 

    private BroadcastReceiver wifiScanReceiver; 

    public FloatWifiManager(Context context) { 
     ... 
     wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 

     // Registering Wifi Receiver 
     wifiScanReceiver = new BroadcastReceiver() { 
      @Override 
      public void onReceive(Context c, Intent intent) { 
       if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { 
        // not getting called, only after running app and manually going to the wifi settings in android 
       } 
      } 
     }; 

     IntentFilter intentFilter = new IntentFilter(); 
     intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); 
     context.registerReceiver(wifiScanReceiver, intentFilter); 
     wifiManager.startScan(); 
    } 

Я зарегистрировал BroadcastReceiver так же, как я видел во всех примерах, и сделал startScan.

Что происходит, список wifi меняется (конечно, я тестировал), но onReceive не вызывается, если я просто останусь в приложении.

onReceive Что делает, наконец, будет называться - это запустить приложение, оставить это работает, и идти в телефон андроид для Настройки ->настройки Wi-Fi. при переходе туда, внезапно обновляется список и вызывается onReceive.

В чем проблема?

  1. Выполняет ли сканирование wifiManager.startScan(); только один раз? или это функция, которая продолжает прослушивать входящие «Результаты сканирования»?

  2. И, очевидно, почему приемник не вызван?

ответ

3

Да, startScan() запрашивает только одно единственное сканирование.

Вы можете избавиться от состояния if (intent.getAction().equals(..)). Все остальное, кажется, в порядке.

просто чтобы понять - моя цель, чтобы иметь приемник, который получит вызывается всякий раз, когда список Wi-Fi сетей меняется, не имея нажать на кнопку «Начать сканирование».

AFAIK Невозможно получить уведомление при изменении любой из сетей Wi-Fi. Вы можете запросить сканирование только с startScan - и, конечно же, вы можете позвонить по телефону startScan с помощью Thread или Handler.

The docs говорит, что SCAN_RESULTS_AVAILABLE_ACTION вызывается, когда «точка доступа сканирование завершено, и результаты доступны от просителя». Как и когда сканирование продолжается, зависит от реализации просителя. Elenkov пишет, что «Android-устройства редко включают оригинальный код wpa_supplicant, включенная реализация часто модифицируется для лучшей совместимости с базовым SoC».


сканирования точек доступа

В этом примере поиск доступных точек доступа и одноранговых сетей. btnScan активирует сканирование, инициированное методом WifiManager.startScan(). После сканирования WifiManager вызывает намерение SCAN_RESULTS_AVAILABLE_ACTION, а класс WifiScanReceiver обрабатывает результат сканирования. Результаты отображаются в TextView.

public class MainActivity extends AppCompatActivity { 

    private final static String TAG = "MainActivity"; 

    TextView txtWifiInfo; 
    WifiManager wifi; 
    WifiScanReceiver wifiReceiver; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     wifi=(WifiManager)getSystemService(Context.WIFI_SERVICE); 
     wifiReceiver = new WifiScanReceiver(); 

     txtWifiInfo = (TextView)findViewById(R.id.txtWifiInfo); 
     Button btnScan = (Button)findViewById(R.id.btnScan); 
     btnScan.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Log.i(TAG, "Start scan..."); 
       wifi.startScan(); 
      } 
     }); 
    } 

    protected void onPause() { 
     unregisterReceiver(wifiReceiver); 
     super.onPause(); 
    } 

    protected void onResume() { 
     registerReceiver(
      wifiReceiver, 
      new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) 
     ); 
     super.onResume(); 
    } 

    private class WifiScanReceiver extends BroadcastReceiver { 
     public void onReceive(Context c, Intent intent) { 
      List<ScanResult> wifiScanList = wifi.getScanResults(); 
      txtWifiInfo.setText(""); 
      for(int i = 0; i < wifiScanList.size(); i++){ 
       String info = ((wifiScanList.get(i)).toString()); 
       txtWifiInfo.append(info+"\n\n"); 
      } 
     } 
    } 
} 

Права доступа

Следующие разрешения должны быть определены в AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 

android.permission.ACCESS_WIFI_STATE необходимо для вызова WifiManager.getScanResults(). Без android.permission.CHANGE_WIFI_STATE вы не можете инициировать сканирование с помощью WifiManager.startScan().

При компиляции проекта для уровня api 23 или выше (Android 6.0 и выше) необходимо установить либо android.permission.ACCESS_FINE_LOCATION, либо android.permission.ACCESS_COARSE_LOCATION. Кроме того, необходимо получить разрешение. в onCreate методе вашей основной деятельности:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    ... 
    String[] PERMS_INITIAL={ 
      Manifest.permission.ACCESS_FINE_LOCATION, 
    }; 
    ActivityCompat.requestPermissions(this, PERMS_INITIAL, 127); 
} 
+0

, что я имел в виду, спрашивая, если его «единый сканирование» было - я буду продолжать получать уведомление в onResponse, когда Wi-Fi сети обновляют? кажется, что это так - потому что, когда я запускаю код и просто перехожу в Настройки -> Настройки Wifi, onResponse получает вызов несколько раз. поэтому, чтобы убедиться, что нет необходимости вызывать startScan() несколько раз, один раз достаточно, правильно? –

+0

только для того, чтобы все было ясно - моя цель иметь приемник, который будет вызываться каждый раз, когда список сетей Wi-Fi меняется, без необходимости нажатия кнопки «начать сканирование». –

+0

Я обновил свой ответ. – gus27

Смежные вопросы