Fulgor3
Fulgor3

Reputation: 499

I can't detect iBeacon in Background using AltBeacon library in Android app

I have an app which I use to get some adverts from concrete iBeacon. I'm doing it right and the bluetooth works great. The problem is that now I pretend to promt or launch something when the user enters a concrete region having the app in background, so I decided to use AltBeacon lib.

I haven't implemented a service, I just do what the tutorial says to start an activity having the app in background: http://altbeacon.github.io/android-beacon-library/samples.html

As I see in the example (the last one) what I did was to set the manifest like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.googlebeacon"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="18"
        android:targetSdkVersion="18" />
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:name="com.example.googlebeacon.MyRegionApp"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.googlebeacon.MainActivity"
            android:label="@string/app_name" 
            android:launchMode="singleInstance">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Once I did that I decided to create another Java class as the advice:

 package com.example.googlebeacon;

    import org.altbeacon.beacon.BeaconConsumer;
    import org.altbeacon.beacon.BeaconManager;
    import org.altbeacon.beacon.BeaconParser;
    import org.altbeacon.beacon.Identifier;
    import org.altbeacon.beacon.RangeNotifier;
    import org.altbeacon.beacon.Region;
    import org.altbeacon.beacon.powersave.BackgroundPowerSaver;
    import org.altbeacon.beacon.startup.BootstrapNotifier;
    import org.altbeacon.beacon.startup.RegionBootstrap;

    import android.app.Application;
    import android.content.Intent;
    import android.util.Log;
    import android.widget.Toast;

    public class MyRegionApp extends Application implements BootstrapNotifier {
        private final String DebugTag="HOLAREGION";
        private RegionBootstrap regionBootstrap;
        private BackgroundPowerSaver backgroundPowerSaver;
        private BeaconManager mBeaconManager;
        private static final String UUID = "0112234-4556-6778-899a-abbccddeeff0";

        @Override
public void onCreate() {
    super.onCreate();
    Log.d(DebugTag, "App started up");
    mBeaconManager = BeaconManager.getInstanceForApplication(this);
    //BeaconManager.getInstanceForApplication(this).getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24"));
    mBeaconManager.setBackgroundScanPeriod(1100l);

    mBeaconManager.setBackgroundBetweenScanPeriod(60000l);

    //Region region = new Region("allbeacons", Identifier.parse(UUID) , null, null);
    Region region = new Region("allbeacons", null , null, null);
    //backgroundPowerSaver = new BackgroundPowerSaver(this);

    regionBootstrap = new RegionBootstrap(this, region);
    BeaconManager.getInstanceForApplication(this).getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24"));
}



        @Override
        public void didDetermineStateForRegion(int arg0, Region arg1) {
            // TODO Auto-generated method stub

        }

        @Override
        public void didEnterRegion(Region arg0) {
            // TODO Auto-generated method stub


            Log.d(DebugTag, "Got a didEnterRegion call");

            regionBootstrap.disable();

            Toast.makeText(getApplicationContext(), "ENTRA EN LA REGION!!!",
                       Toast.LENGTH_LONG).show();

            Intent intent = new Intent(this, MainActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            this.startActivity(intent);

        }

        @Override
        public void didExitRegion(Region arg0) {
            // TODO Auto-generated method stub
            Log.d(DebugTag, "Got a didExitRegion call");
        }




    }

And if I use:

// set the duration of the scan to be 1.1 seconds
            //mBeaconManager.setBackgroundScanPeriod(1100l);
         // set the time between each scan to be 1 minute (60 seconds)
            //mBeaconManager.setBackgroundBetweenScanPeriod(60000l);

The app crashes and doesn't show the MainActivity I have, it tries but is closed in a blink.

Error LogCat: FIXED ADDING mBeaconManager = BeaconManager.getInstanceForApplication(this);

11-07 14:17:22.791: W/System.err(2125): java.lang.RuntimeException: Unable to create application com.example.googlebeacon.MyRegionApp: java.lang.NullPointerException: Attempt to invoke virtual method 'void org.altbeacon.beacon.BeaconManager.setBackgroundScanPeriod(long)' on a null object reference
11-07 14:17:22.791: W/System.err(2125):     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4433)
11-07 14:17:22.791: W/System.err(2125):     at android.app.ActivityThread.access$1500(ActivityThread.java:142)
11-07 14:17:22.791: W/System.err(2125):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1263)
11-07 14:17:22.791: W/System.err(2125):     at android.os.Handler.dispatchMessage(Handler.java:102)
11-07 14:17:22.791: W/System.err(2125):     at android.os.Looper.loop(Looper.java:136)
11-07 14:17:22.791: W/System.err(2125):     at android.app.ActivityThread.main(ActivityThread.java:5118)
11-07 14:17:22.791: W/System.err(2125):     at java.lang.reflect.Method.invoke(Native Method)
11-07 14:17:22.791: W/System.err(2125):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
11-07 14:17:22.791: W/System.err(2125):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:610)
11-07 14:17:22.791: W/System.err(2125): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void org.altbeacon.beacon.BeaconManager.setBackgroundScanPeriod(long)' on a null object reference
11-07 14:17:22.791: W/System.err(2125):     at com.example.googlebeacon.MyRegionApp.onCreate(MyRegionApp.java:31)
11-07 14:17:22.791: W/System.err(2125):     at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1007)
11-07 14:17:22.791: W/System.err(2125):     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4430)
11-07 14:17:22.791: W/System.err(2125):     ... 8 more

I have added to my project.properties the following line and it still doesn't work:

manifestmerger.enabled=true

Adding this last line I was able to detect the iBeacon as I start the app but now in the background although I set the setBackground ScanPeriod and BetweenScanPeriod to 1100l and to 60000l in order to increase the scan frequency, but I'm not able to see anything in Background.

Using the example app provided as example I can detect my iBeacon without any problem (downloaded from here https://github.com/AltBeacon/android-beacon-library-reference).

Any help will be very appreciated. I'm very novice in Android programming, please be a bit patient, I'm doing my best.

Regards.

Iván

Upvotes: 1

Views: 6246

Answers (2)

davidgyoung
davidgyoung

Reputation: 64916

If you are using Eclipse, check to be sure you have properly enabled manifest merging per the instructions here: http://altbeacon.github.io/android-beacon-library/configure.html

Edit your project.properties file and add the line: manifestmerger.enabled=true

Upvotes: 1

davidgyoung
davidgyoung

Reputation: 64916

Understand that the Android Beacon Library 2.0 is designed to be free of intellectual property so it can be open source. This means that it will not detect proprietary beacons out of the box, and only detects beacons conforming to the AltBeacon standard.

If you are using different beacons that transmit a proprietary format, you must supply the format of those beacons to the library. You can do this by adding a line of code that looks like below:

// IMPORTANT: replace the string in setBeaconLayout() with one that describes the format
// of your proprietary beacon
beaconManager.getBeaconParsers().add(new BeaconParser().
           setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));

As the comment mentions above, you will need to find a string for your proprietary beacon type. To see how others have done this, try doing a Google search for "setBeaconLayout" (include the quotes) and find the beacon layout expression for the type of beacon you have.

Upvotes: 2

Related Questions