androidandroid-wifijava-threadsindoor-positioning-system

Android: Scan all APs (access points) continuously


I am fairly new to android application development. I am working on an android application to ping access points to access their RSSI values to estimate a user's location.

While I currently have this 'working', I believe there to be a bug within my implementation that is creating too many calls to "onReceive()". Over the life of the application, the amount of calls to this function ramps up on a linear scale.

My goal with the code I'm about to post is to simply scan WiFi access points, get their RSSI values and then continuously loop. Battery life is no issue, performance is a much more important metric.

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

Then in the same file, in the onCreate() method:

handler.post(locationUpdate);

Then in the same file, outside of the onCreate() method:

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

        }
    }
};

I confirmed the ramping/thread problem because I incremented and output to the console when the program reaches "sortScan(scan)", and you can clearly see that the results are linearly ramping.

Like I said early, my intention is to simply re-scan as soon as the first scan finishes and loop it for the entire life of the application.

Any help will be greatly appreciated, thank you.


Solution

  • You are repeatedly registering your receiver which is not necessary.Just register the WifiScanReceiver only once in onCreate(). Then call start scan in the getLocation() function.

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

    You should not do heavy processing in the onReceive(). Arrange a callback to the Activity to do that.