Да, 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);
}
, что я имел в виду, спрашивая, если его «единый сканирование» было - я буду продолжать получать уведомление в onResponse, когда Wi-Fi сети обновляют? кажется, что это так - потому что, когда я запускаю код и просто перехожу в Настройки -> Настройки Wifi, onResponse получает вызов несколько раз. поэтому, чтобы убедиться, что нет необходимости вызывать startScan() несколько раз, один раз достаточно, правильно? –
только для того, чтобы все было ясно - моя цель иметь приемник, который будет вызываться каждый раз, когда список сетей Wi-Fi меняется, без необходимости нажатия кнопки «начать сканирование». –
Я обновил свой ответ. – gus27