我应该在Android上的每个无线扫描之间使用的是什么时间?的是、时间、Android

2023-09-05 09:28:06 作者:嗲女

我需要定期执行无线扫描。我遇到问题时的时间间隔设定为1-2秒。好像我没有收到任何ScanResult。是否有时间来设定,使​​得WifiManager能够执行一次成功的WiFi扫描的最小量α

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?

下面是code。我使用的是服务做了WiFi扫描:

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);
      }
    }
  }
}

不过,我似乎得到空指针在该行: apdataList.add(AP); 。所以,我不知道时间是否过短,导致ScanResult是空的?

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?

推荐答案

修改您发布您的code后:

EDIT after you posted your code:

apdataList似乎并没有在的onCreate进行初始化()

apdataList does not seem to be initialized in onCreate()

这增加的onCreate():

add this to onCreate():

apdataList = new List<APData>();

最小扫描延迟

我觉得没有绝对的最小扫描延迟。它过于依赖硬件的性能。

I think that there is no absolute minimum scanning delay. It depends too much on the hardware performances.

我的建议是,你加一个尽可能快地选择你的preferences然后使用,一旦新的结果发现重新启动扫描异步循环(请参见下面的code片段,它已更新,以满足您的需求)。这样一来,就只能通过硬件性能的限制。

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.

您也可以使用轮询ScanResults WifiManager.getScanResults()推荐的方法是启动 WifiManager.startScan()并成立了一个BroadcastReceiver为 WifiManager.SCAN_RESULTS_AVAILABLE_ACTION 被通知一旦扫描结果都准备好了。

Also you can poll the ScanResults using WifiManager.getScanResults() The recommended way is to launch WifiManager.startScan() and set up a BroadcastReceiver for WifiManager.SCAN_RESULTS_AVAILABLE_ACTION to be notified as soon as the scan results are ready.

下面是一个示例code(借from这里并适应您的需求):

Here's a sample code (borrowed from here and adapted to your needs):

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.getSystemService(Context.WIFI_SERVICE); 
      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) getSystemService(Context.WIFI_SERVICE); 
    boolean a = wm.startScan();