我无法在Android应用中使用AltBeacon库在后台检测iBeacon

时间:2014-11-07 10:25:48

标签: android bluetooth bluetooth-lowenergy ibeacon altbeacon

我有一个应用程序,我用来从具体的iBeacon获得一些广告。我做得对,蓝牙效果很好。问题是,当用户进入具有后台应用程序的具体区域时,现在我假装推出或启动某些东西,所以我决定使用AltBeacon lib。

我还没有实现服务,我只是按照教程所说的开始在后台启动应用程序的活动: http://altbeacon.github.io/android-beacon-library/samples.html

正如我在示例中看到的那样(最后一个),我所做的就是像这样设置清单:

<?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>

一旦我这样做,我决定创建另一个Java类作为建议:

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




    }

如果我使用:

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

应用程序崩溃并且没有显示我的MainActivity,它会尝试但是会在瞬间关闭。

错误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

我已经在我的project.properties中添加了以下行,它仍然不起作用:

manifestmerger.enabled=true

添加最后一行我能够在启动应用程序时检测iBeacon,但现在在后台虽然我将setBackground ScanPeriod和BetweenScanPeriod设置为1100l和60000l以提高扫描频率,但我不是能够在背景中看到任何东西。

使用作为示例提供的示例应用程序,我可以毫无问题地检测到我的iBeacon(从此处https://github.com/AltBeacon/android-beacon-library-reference下载)。

任何帮助将非常感谢。 我是Android编程的新手,请耐心点,我正在努力。

问候。

伊万

2 个答案:

答案 0 :(得分:2)

了解Android Beacon Library 2.0旨在免于知识产权,因此它可以是开源的。这意味着它不会检测到开箱即用的专有信标,只检测符合AltBeacon standard.的信标

如果您使用传输专有格式的不同信标,则必须将这些信标的格式提供给库。您可以通过添加如下所示的代码行来完成此操作:

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

正如上面提到的评论,您需要找到专有信标类型的字符串。要了解其他人如何做到这一点,请尝试在Google搜索&#34; setBeaconLayout&#34; (包括引号)并找到您所拥有的信标类型的信标布局表达式。

答案 1 :(得分:1)

如果您使用的是Eclipse,请检查以确保您已根据此处的说明正确启用了清单合并:http://altbeacon.github.io/android-beacon-library/configure.html

  

编辑project.properties文件并添加以下行:manifestmerger.enabled=true