【问题标题】:Late initialisation of RegionBootstrapRegionBootstrap 的后期初始化
【发布时间】:2015-02-20 04:45:24
【问题描述】:

在参考应用程序中,RegionBootstrap 在其onCreate 方法 上的自定义应用程序类 中初始化,当然,在调用任何活动之前调用应用程序类。

有没有办法在活动中初始化 RegionBootstrap?我已经尝试过制作 RegionBootstrap 的静态变量,以便我可以在不同的活动中调用它,但不幸的是,它不起作用。

BeaconApplication.regionBootstrap = new RegionBootstrap((BootstrapNotifier) this.getApplication(), downloadedBeacons);

我需要初始化的 Regions 将来自服务器,因此 RegionBootstrap 的初始化不能来自应用程序类。

* 编辑 *

public class LoginActivity extends ActionBarActivity {
    …
    /*** short version ***/
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        /*** after successful login ***/
        BeaconApplication.beacons = downloadBeaconsFromServer();    
    }
}

public class BeaconActivity extends ActionBarActivity {
    …
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        …
        startService(new Intent(this, BeaconService.class));
    }
}

这是我实现BeaconConsumer的地方

public class BeaconService extends Service implements BeaconConsumer {
    private BeaconManager beaconManager;
    private BeaconNotifier beaconNotifier;
    private RegionBootstrap regionBootstrap;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "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"));
        beaconManager.setBackgroundBetweenScanPeriod(1001);
        beaconManager.setBackgroundScanPeriod(101);
        beaconManager.setForegroundScanPeriod(101);
        beaconManager.setForegroundBetweenScanPeriod(1001);
        beaconNotifier = new BeaconNotifier(this);
        beaconManager.bind(this);
    }

    @Override
    public void onBeaconServiceConnect() {
        beaconManager.setMonitorNotifier(beaconNotifier);
        monitorBeacons();

        regionBootstrap = new RegionBootstrap(beaconNotifier, BeaconApplication.beacons);
    }

    private void monitorBeacons() {
        for (Region beacon : BeaconApplication.beacons) {
            try {
                Log.i(TAG, "Monitoring beacon " + beacon.getUniqueId());
                beaconManager.startMonitoringBeaconsInRegion(beacon);
            } catch (RemoteException e) {
                Log.e(TAG, "Monitoring beacon failed");
                e.printStackTrace();
            }
        }
    }
}

BeaconNotifier的实现

public class BeaconNotifier implements BootstrapNotifier {
    private Context context;

    public BeaconNotifier(Context context) {
            this.context = context;
    }

    @Override
    didEnter.. etc

    @Override
    public Context getApplicationContext() {
            return context;
    }
}

【问题讨论】:

    标签: android altbeacon android-ibeacon


    【解决方案1】:

    你可以使用:

    BeaconManager.setMonitorNotifier(MonitorNotifier);
    BeaconManager.startMonitoringBeaconsInRegion(Region);
    

    但是不要忘记,要使用BeaconManager 方法,您必须等到BeaconService 连接。请注意,使用这种方法,如果您想监控信标,即使应用程序被杀死,您也需要创建自己的服务。

    顺便说一句,我记得,曾经我也遇到过RegionBootstrap 的问题。我使用了一个技巧来处理这个问题。你能测试下面的代码吗?

    ...
    BeaconManager.bind(yourConsumer);
    ...
    //wait until BeaconConsumer.onBeaconServiceConnect() is called
    //write following code inside of onBeaconServiceConnect
    RegionBootstrap dummy = new RegionBootstrap(mBootstrapNotifier, new Region("dummy", null, null, null));
    dummy.disable();
    //after this point you can create your own RegionBootstrap
    

    这里有一个关键点,你需要创建自己的BootstrapNotifier。如果你在活动中这样做,你可以这样做:

    public class YourActivity extends Activity implements BootstrapNotifier {
        ...
        BootstrapNotifier mBootstrapNotifier = this;
        ...
    

    或者在Application 类中:

    public class YourApp extends Application implements BootstrapNotifier {
        ...
        BootstrapNotifier mBootstrapNotifier = this;
        ...
    

    就我而言,我创建了一个适配器,该适配器在其构造函数中需要Context,并且我将该适配器用作BootstrapNotifier

    public class AltBeaconAdapter implements BootstrapNotifier {
        private Context mContext;
        ...
    
        public AltBeaconAdapter(Context context) {
            mContext = context;
            ...
        }
    
        @Override
        public Context getApplicationContext() {
            return mContext;
        }
    
        ...
    }
    

    此外,您必须实现MonitorNotifier 方法,因为BootstrapNotifierMonitorNotifier 的子类。

    是的,这个技巧很奇怪,它显示在初始化 RegionBootstrap 时库中存在错误,但我有服务,所以我切换到了我向您提出的第一种方法。如果这个技巧也适用于你,请告诉我,以便我可以在库的 GitHub 页面上创建问题。

    【讨论】:

    • 即使在 android 杀死应用程序后,这些方法是否会从后台打开应用程序并监视信标? altbeacon.github.io/android-beacon-library/…
    • 我已经更新了我的答案,请检查一下,让我知道它是否适合你。
    • RegionBootstrap 需要两个参数,而不仅仅是我的问题中所述的 Region。我试过这个RegionBootstrap dummy = new RegionBootstrap((BootstrapNotifier) getApplicationContext(), new Region("dummy", null, null, null));,但我得到了这个错误java.lang.ClassCastException: com.tektosworld.ibeaconmobileapp.BeaconApplication cannot be cast to org.altbeacon.beacon.startup.BootstrapNotifier。当我没有将 BootstrapNotifier 放在 Application 类中时,这与我遇到的相同错误。
    • 对不起,那是我的错。我再次更新了我的答案。我希望这一次它会帮助你:)。顺便说一句,RegionBootstrap 需要一个BootstrapNotifier,而您只提供一个导致ClassCastExceptionApplication 对象。你应该在你的com.tektosworld.ibeaconmobileapp.BeaconApplication 类中实现BootstrapNotifier。让我知道是否可以为您提供更多帮助。
    • 实现 BootstrapNotifier 是否意味着我不应该再实现 BeaconConsumer 了?另外,如果我在服务中实现 BootstrapNotifier,这会改变什么吗?
    猜你喜欢
    • 2021-08-29
    • 2021-09-25
    • 1970-01-01
    • 2021-10-16
    • 2015-12-20
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多