Android 上每次 WiFi 扫描之间应该使用什么间隔?
我需要定期执行 Wifi 扫描。当时间间隔设置为 1-2 秒时,我遇到了问题。我似乎没有收到任何 ScanResult
。是否需要设置最短时间,以便 WifiManager
能够成功执行 WiFi 扫描?
这是代码。我正在使用 Service
进行 Wifi 扫描:
public class WifiScanning extends Service{
private static final String TAG = "WifiScanning";
private Timer timer;
public int refreshRate, numberOfWifiScan, wifiScanGranularity;
WifiReceiver receiverWifi = new WifiReceiver();
WifiManager wifi;
StringBuilder sb;
List<ScanResult> wifiList;
List<APData> apdataList;
List<List<APData>>surveyData;
private TimerTask updateTask = new TimerTask() {
@Override
public void run() {
Log.i(TAG, "Timer task doing work");
wifi.startScan();
}
};
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Service creating");
//retrieve the mapRefreshRate from config.xml
XMLOperations test = new XMLOperations();
Configuration config = new Configuration();
config = test.saxXmlParsing(this, 1);
if(config==null)
config = test.saxXmlParsing(this, 2);
refreshRate = Integer.parseInt(config.getMapRefreshRate());
numberOfWifiScan = Integer.parseInt(config.getNumberOfWifiScan_Positioning());
wifiScanGranularity = Integer.parseInt(config.getWifiScanGranularity_Positioning());
timer = new Timer();
Log.i(TAG, "Refresh Rate: "+ String.valueOf(refreshRate));
timer.schedule(updateTask, 0, refreshRate);
wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
registerReceiver(receiverWifi, new IntentFilter(
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "Service destroying");
unregisterReceiver(receiverWifi);
if (timer != null){
timer.cancel();
timer.purge();
timer = null;
}
}
class WifiReceiver extends BroadcastReceiver {
public void onReceive(Context c, Intent intent) {
sb = new StringBuilder();
wifiList = wifi.getScanResults();
String ap_ssid;
String ap_mac;
Double ap_rssi;
for(int i = 0; i < wifiList.size(); i++){
ap_ssid = wifiList.get(i).SSID;
ap_mac = wifiList.get(i).BSSID;
ap_rssi = Double.valueOf(wifiList.get(i).level);
APData ap = new APData(ap_ssid,ap_mac,ap_rssi);
apdataList.add(ap);
sb.append(" " + (wifiList.get(i).SSID).toString());
sb.append(" " + (wifiList.get(i).BSSID).toString());
sb.append((" " + String.valueOf(wifiList.get(i).level)));
sb.append("\n");
}
Log.d(TAG, sb.toString());
for(int i=1; i<=numberOfWifiScan; i++){
surveyData.add(apdataList);
}
}
}
}
但是,我似乎在这一行得到 Nullpointer
:apdataList.add(ap);
。所以我想知道是否是间隔太短,导致ScanResult
为空?
I need to perform Wifi scans at regular intervals. I am encountering a problem when the time interval is set to 1-2 seconds. It seems like I am not getting any ScanResult
. Is there a minimum amount of time to set so that the WifiManager
is able to perform a successful WiFi scan?
Here is the code. I am using a Service
to do the Wifi scan:
public class WifiScanning extends Service{
private static final String TAG = "WifiScanning";
private Timer timer;
public int refreshRate, numberOfWifiScan, wifiScanGranularity;
WifiReceiver receiverWifi = new WifiReceiver();
WifiManager wifi;
StringBuilder sb;
List<ScanResult> wifiList;
List<APData> apdataList;
List<List<APData>>surveyData;
private TimerTask updateTask = new TimerTask() {
@Override
public void run() {
Log.i(TAG, "Timer task doing work");
wifi.startScan();
}
};
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Service creating");
//retrieve the mapRefreshRate from config.xml
XMLOperations test = new XMLOperations();
Configuration config = new Configuration();
config = test.saxXmlParsing(this, 1);
if(config==null)
config = test.saxXmlParsing(this, 2);
refreshRate = Integer.parseInt(config.getMapRefreshRate());
numberOfWifiScan = Integer.parseInt(config.getNumberOfWifiScan_Positioning());
wifiScanGranularity = Integer.parseInt(config.getWifiScanGranularity_Positioning());
timer = new Timer();
Log.i(TAG, "Refresh Rate: "+ String.valueOf(refreshRate));
timer.schedule(updateTask, 0, refreshRate);
wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
registerReceiver(receiverWifi, new IntentFilter(
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "Service destroying");
unregisterReceiver(receiverWifi);
if (timer != null){
timer.cancel();
timer.purge();
timer = null;
}
}
class WifiReceiver extends BroadcastReceiver {
public void onReceive(Context c, Intent intent) {
sb = new StringBuilder();
wifiList = wifi.getScanResults();
String ap_ssid;
String ap_mac;
Double ap_rssi;
for(int i = 0; i < wifiList.size(); i++){
ap_ssid = wifiList.get(i).SSID;
ap_mac = wifiList.get(i).BSSID;
ap_rssi = Double.valueOf(wifiList.get(i).level);
APData ap = new APData(ap_ssid,ap_mac,ap_rssi);
apdataList.add(ap);
sb.append(" " + (wifiList.get(i).SSID).toString());
sb.append(" " + (wifiList.get(i).BSSID).toString());
sb.append((" " + String.valueOf(wifiList.get(i).level)));
sb.append("\n");
}
Log.d(TAG, sb.toString());
for(int i=1; i<=numberOfWifiScan; i++){
surveyData.add(apdataList);
}
}
}
}
However, I seem to get Nullpointer
at this line: apdataList.add(ap);
. So I wonder whether the interval is too short, which causes ScanResult
to be empty?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
编辑发布代码后:
apdataList似乎没有在onCreate()中初始化
,将其添加到onCreate():
最小扫描延迟
我认为没有绝对的最小值扫描延迟。这很大程度上取决于硬件性能。
我的建议是,您在首选项中添加“尽可能快”选项,然后使用异步循环,一旦发现新结果就重新启动扫描(请参阅下面的代码片段,它已更新以满足您的需求)。这样,它只会受到硬件性能的限制。
您还可以使用
WifiManager 轮询 ScanResults。 getScanResults()
推荐的方法是启动WifiManager.startScan()
并设置一个 BroadcastReceiverWifiManager.SCAN_RESULTS_AVAILABLE_ACTION
扫描结果准备就绪后立即收到通知。以下是示例代码(从此处借用并适应您的需求):
EDIT after you posted your code:
apdataList does not seem to be initialized in onCreate()
add this to onCreate():
Minimum scanning delay
I think that there is no absolute minimum scanning delay. It depends too much on the hardware performances.
My advice is that you add a 'As Fast As Possible' option to your preferences then use an asynchronous loop that relaunch a scan as soon as new results are found (see the code snippet below, it was updated to suit your needs). This way, it will only be limited by hardware performances.
Also you can poll the ScanResults using
WifiManager.getScanResults()
The recommended way is to launchWifiManager.startScan()
and set up a BroadcastReceiver forWifiManager.SCAN_RESULTS_AVAILABLE_ACTION
to be notified as soon as the scan results are ready.Here's a sample code (borrowed from here and adapted to your needs):
从 Android 8 及更高版本开始,限制为2 分钟内 4 次。
因此,您可以扫描 4 次,中间有 1 秒的延迟。但在接下来的 126 秒内您将不会获得任何进一步的扫描结果。
因此,每次扫描成功的最快间隔是每 30 秒。
From Android 8 and higher, the limit is 4 times in 2 minutes.
So you could scan 4 times with 1 second of delay in between. But you would not get any further scan results for the next 126 seconds.
So the fastest interval where every scan is successful would be every 30 seconds.