【问题标题】:Android: Scan all APs (access points) continuouslyAndroid:连续扫描所有AP(接入点)
【发布时间】:2025-12-06 15:00:01
【问题描述】:

我对 android 应用程序开发相当陌生。我正在开发一个 android 应用程序来 ping 接入点以访问其 RSSI 值以估计用户的位置。

虽然我目前有这个“工作”,但我相信我的实现中存在一个错误,它会创建太多对“onReceive()”的调用。在应用程序的整个生命周期中,对该函数的调用量呈线性增长。

我即将发布的代码的目标是简单地扫描 WiFi 接入点,获取它们的 RSSI 值,然后不断循环。电池寿命不是问题,性能是一个更重要的指标。

MainActivity.java:

Handler handler = new Handler();
final Runnable locationUpdate = new Runnable() {
    @Override
    public void run() {
        getLocation();

      //customView.setLocation(getX_pixel(curLocation.getX()), getY_pixel(curLocation.getY()));
       //customView.invalidate();

        handler.postDelayed(locationUpdate, 1000);
    }
};

private void getLocation() {
    Context context = getApplicationContext();
    WifiScanReceiver wifiReceiver = new WifiScanReceiver();
    registerReceiver(wifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
    WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    wifiManager.startScan();
    Log.d("START SCAN CALLED", "");
}

然后在同一个文件中,在 onCreate() 方法中:

handler.post(locationUpdate);

然后在同一个文件中,在 onCreate() 方法之外:

class WifiScanReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context c, Intent intent) {
        WifiManager wifiManager = (WifiManager) c.getSystemService(Context.WIFI_SERVICE);

        List<ScanResult> scan = wifiManager.getScanResults();
        // Application specific code:
        sortScan(scan);
        count+= 1;
        System.out.println("Count: " + count);

        }
    }
};

我确认了斜坡/线程问题,因为我在程序到达“sortScan(scan)”时递增并输出到控制台,您可以清楚地看到结果是线性斜坡。

就像我之前说的,我的意图是在第一次扫描完成后立即重新扫描,并在应用程序的整个生命周期内循环它。

任何帮助将不胜感激,谢谢。

【问题讨论】:

    标签: android android-wifi java-threads indoor-positioning-system


    【解决方案1】:

    您正在重复注册您的接收器,这是不必要的。只需在 onCreate() 中注册一次 WifiScanReceiver。然后在getLocation()函数中调用start scan。

     WifiManager wifiManager;
     @Override
    protected void onCreate(Bundle savedInstanceState) {
        Context context = getApplicationContext();
        WifiScanReceiver wifiReceiver = new WifiScanReceiver();
        registerReceiver(wifiReceiver, new 
                     IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
        wifiManager =
                    (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
    
    
    
    Handler handler = new Handler();
    final Runnable locationUpdate = new Runnable() {
        @Override
        public void run() {
            getLocation();
            //This line will continuously call this Runnable with 1000 milliseconds gap
            handler.postDelayed(locationUpdate, 1000);
        }
    };
    
    private void getLocation() {
        wifiManager.startScan();
        Log.d("START SCAN CALLED", "");
    }
    
    }
    
    
     class WifiScanReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context c, Intent intent) {
    
       if(intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)){
    
            //New scan results are available. Arrange a callback to the activity here.
        }
      }
    }
    

    您不应该在 onReceive() 中进行繁重的处理。安排对 Activity 的回调来执行此操作。

    【讨论】:

      【解决方案2】:

      每次运行getLocation() 时,您都会创建一个新的广播接收器。这些接收者中的每一个都会收到WifiManager.SCAN_RESULTS_AVAILABLE_ACTION 广播。尝试在适当的上下文中分配和注册一次接收器,并且只在getLocation() 中调用startScan()

      【讨论】:

        【解决方案3】:

        连续循环扫描 WiFi AP 的 RSSI 值的最佳方法是在 OnCreate 中简单地开始第一次扫描。然后在BroadcastReceiver的onReceive回调中,再次调用start scan。

        【讨论】: