TimmAy
TimmAy

Reputation: 33

Error when running BeaconManager.bind inside a method ALTBeacon

My scanner class extends Application and implements BeaconConsumer. When I try to bind or unbind the BeaconManager I get a NullPointerException.

public class Scanner extends Application implements BeaconConsumer{
private BeaconManager beaconManager;

@Override
public void onCreate() {
    try {
        super.onCreate();

        beaconManager = BeaconManager.getInstanceForApplication(this);
        beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(" m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));

    }
    catch (Exception e){
        e.printStackTrace();
    }

}


public void startScan(long period){
    try {
        if (beaconManager==null) {
            beaconManager = BeaconManager.getInstanceForApplication(Scanner.this);
            beaconManager.bind(Scanner.this);
            beaconManager.setForegroundScanPeriod(period);
            beaconManager.updateScanPeriods();
        }
    }
    catch (Exception e){
        e.printStackTrace();
    }
}

public void stopScan(){
    beaconManager.unbind(Scanner.this);
}

I get the following error :

W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'void org.altbeacon.beacon.BeaconManager.bind(org.altbeacon.beacon.BeaconConsumer)' on a null object reference

Upvotes: 3

Views: 449

Answers (1)

davidgyoung
davidgyoung

Reputation: 64941

I suspect the problem is that there are multiple instances of the Scanner class running. In general you should not ever manually create an instance of an Android Application class (one that extends Application). You declare such a class in the AndroidManifest.xml, and let the Android OS instantiate it when it starts up the app. If you manually instantiate the class by calling its constructor, the onCreate() method will not get called and the beaconManager will not get created.

If you want to get an instance of this class from an Activity so you can call methods like startScan() or stopScan() you can use:

Scanner scanner = (Scanner) this.getApplication();

Be careful, also, about two other issues with the way the code is written:

  1. If you call startScan(), stopScan(), startScan(), nothing will happen on the second startScan() call because beaconManager will not be nil. Scanning will not restart.

  2. The call to beaconManager.updateScanPeriods(); will fail if the asynchronous bind(...); call before it has not completed (usually it will not), causing the code to fall into the catch block. An easy fix is to remove that call to beaconManager.updateScanPeriods(); and simply move the beaconManager.setForegroundScanPeriod(period); call before the call to bind(...).

Upvotes: 1

Related Questions