Android 上每次 WiFi 扫描之间应该使用什么间隔?

发布于 2024-12-07 14:53:21 字数 3006 浏览 0 评论 0原文

我需要定期执行 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);
      }
    }
  }
}

但是,我似乎在这一行得到 NullpointerapdataList.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

月光色 2024-12-14 14:53:21

编辑发布代码后:

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

,将其添加到onCreate():

apdataList = new List<APData>();

最小扫描延迟

我认为没有绝对的最小值扫描延迟。这很大程度上取决于硬件性能。

我的建议是,您在首选项中添加“尽可能快”选项,然后使用异步循环,一旦发现新结果就重新启动扫描(请参阅下面的代码片段,它已更新以满足您的需求)。这样,它只会受到硬件性能的限制。


您还可以使用 WifiManager 轮询 ScanResults。 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(); 

EDIT after you posted your code:

apdataList does not seem to be initialized in onCreate()

add this to onCreate():

apdataList = new List<APData>();

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 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.

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.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(); 
百变从容 2024-12-14 14:53:21

从 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文