Android:持续扫描所有AP(接入点)

时间:2017-06-13 03:29:12

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

我对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(扫描)”时,我增加并输出到控制台,你可以清楚地看到结果是线性斜坡。

就像我早期说的那样,我的目的是在第一次扫描完成后立即重新扫描并在应用程序的整个生命周期内循环。

非常感谢任何帮助,谢谢。

3 个答案:

答案 0 :(得分: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()中进行繁重的处理。安排对活动的回调来做到这一点。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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