连续的 WifiManager 扫描得到重复的扫描结果
Consecutive WifiManager scans getting repeated Scan Results
我在定时器里有这个:
if (wManager.startScan()) {
try {
//Following method is one I call to process the results
acquireCurrentZoneFromServer.run(client, wManager.getScanResults());
} catch (Exception e) {
e.printStackTrace();
}
}
这很好用。但是,当我以较小的间隔(例如 1 秒)将计时器设置为 运行 时,我得到的结果会以 2 为一组重复。
有什么解决方法吗?
我认为,您的解决方案是错误的。您不需要每 1 秒或任何其他时间间隔检查一次扫描结果。您应该创建 BroadcastReceiver。 BroadcastReceiver 将在获得扫描结果时通知您的应用程序。名为 startScan()
的方法不保证结果的交付时间。当您尝试每 1 秒读取一次扫描结果时,它不是确定性的。你可能会收到一些东西,但你也可能不会。然而,计时器正在运行,这会降低性能并耗尽电池电量,因此此解决方案效率不高。
下面是展示想法的示例代码片段:
final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
wifiManager.startScan(); // without starting scan, we may never receive any scan results
final IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.RSSI_CHANGED_ACTION); // you can keep this filter if you want to get fresh results when singnal stregth of the APs was changed
filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
wifiManager.startScan();
final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
wifiManager.startScan(); // start scan again to get fresh results ASAP
wifiManager.getScanResults();
}
};
context.registerReceiver(receiver, filter);
// don't forget to unregister receiver when appropriate
// context.unregisterReceiver(receiver);
您可以根据需要调整此代码段。
如果需要,您也可以使用我的库 ReactiveWiFi available at https://github.com/pwittchen/ReactiveWiFi。它允许您使用 RxJava Observables 监控 WiFi 接入点的变化,如下所示:
new ReactiveWifi().observeWifiAccessPoints(context)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<List<ScanResult>>() {
@Override public void call(List<ScanResult> scanResults) {
// do something with scanResults
}
});
这个解决方案也在后台使用 BroadcastReceiver 类似于第一个代码片段,但它被 observable 包裹,所以使用更简单。
我在定时器里有这个:
if (wManager.startScan()) {
try {
//Following method is one I call to process the results
acquireCurrentZoneFromServer.run(client, wManager.getScanResults());
} catch (Exception e) {
e.printStackTrace();
}
}
这很好用。但是,当我以较小的间隔(例如 1 秒)将计时器设置为 运行 时,我得到的结果会以 2 为一组重复。 有什么解决方法吗?
我认为,您的解决方案是错误的。您不需要每 1 秒或任何其他时间间隔检查一次扫描结果。您应该创建 BroadcastReceiver。 BroadcastReceiver 将在获得扫描结果时通知您的应用程序。名为 startScan()
的方法不保证结果的交付时间。当您尝试每 1 秒读取一次扫描结果时,它不是确定性的。你可能会收到一些东西,但你也可能不会。然而,计时器正在运行,这会降低性能并耗尽电池电量,因此此解决方案效率不高。
下面是展示想法的示例代码片段:
final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
wifiManager.startScan(); // without starting scan, we may never receive any scan results
final IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.RSSI_CHANGED_ACTION); // you can keep this filter if you want to get fresh results when singnal stregth of the APs was changed
filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
wifiManager.startScan();
final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
wifiManager.startScan(); // start scan again to get fresh results ASAP
wifiManager.getScanResults();
}
};
context.registerReceiver(receiver, filter);
// don't forget to unregister receiver when appropriate
// context.unregisterReceiver(receiver);
您可以根据需要调整此代码段。
如果需要,您也可以使用我的库 ReactiveWiFi available at https://github.com/pwittchen/ReactiveWiFi。它允许您使用 RxJava Observables 监控 WiFi 接入点的变化,如下所示:
new ReactiveWifi().observeWifiAccessPoints(context)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<List<ScanResult>>() {
@Override public void call(List<ScanResult> scanResults) {
// do something with scanResults
}
});
这个解决方案也在后台使用 BroadcastReceiver 类似于第一个代码片段,但它被 observable 包裹,所以使用更简单。