7

我需要定期执行 Wifi 扫描。当时间间隔设置为 1-2 秒时,我遇到了问题。好像我没有得到任何ScanResult. 是否有最短时间设置以便WifiManager能够成功执行 WiFi 扫描?

这是代码。我正在使用 aService进行 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为空?

4

2 回答 2

13

发布代码后编辑:

apdataList 似乎没有在 onCreate() 中初始化

将此添加到 onCreate():

apdataList = new List<APData>();

最小扫描延迟

我认为没有绝对的最小扫描延迟。这太依赖于硬件性能了。

我的建议是您在首选项中添加“尽可能快”选项,然后使用异步循环,在找到新结果后立即重新启动扫描(请参阅下面的代码片段,它已根据您的需要进行了更新)。这样,它只会受到硬件性能的限制。


您也可以使用 推荐的方法来轮询 ScanResultsWifiManager.getScanResults()是启动WifiManager.startScan()并设置一个 BroadcastReceiver 以便WifiManager.SCAN_RESULTS_AVAILABLE_ACTION在扫描结果准备好后立即收到通知。

这是一个示例代码(从这里借来并适应您的需要):

IntentFilter i = new IntentFilter(); 
i.addAction (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); 
registerReceiver(new BroadcastReceiver(){ 
      public void onReceive(Context c, Intent i){ 
      // Code to execute when SCAN_RESULTS_AVAILABLE_ACTION event occurs 
      WifiManager w = (WifiManager) c.getApplicationContext().getSystemService(Context.WIFI_SERVICE); //Use getApplicationContext to prevent memory leak
      myScanResultHandler(w.getScanResults()); // your method to handle Scan results
      if (ScanAsFastAsPossible) w.startScan(); // relaunch scan immediately
      else { /* Schedule the scan to be run later here */}
      } 
    }, i ); 


    // Launch  wifiscanner the first time here (it will call the broadcast receiver above)
    WifiManager wm = (WifiManager)getApplicationContext.getSystemService(Context.WIFI_SERVICE); 
    boolean a = wm.startScan(); 
于 2011-10-02T07:43:05.890 回答
0

从 Android 8 及更高版本开始,限制为2 分钟内 4 次。所以你可以扫描 4 次,中间有 1 秒的延迟。但在接下来的 126 秒内,您不会得到任何进一步的扫描结果。

因此,每次扫描成功的最快间隔是每 30 秒

于 2020-11-30T12:30:07.293 回答