How to range beacons in background using Altbeacon: Android Beacon Library?

混江龙づ霸主 提交于 2020-01-14 03:17:08

问题


I'm developing an app which provides background Beacon monitoring. I would like to start ranging when user enters beacon from defined region. When app is in background and it's monitoring all the time and user enters my defined region I would like to start ranging and get InstanceID or Major, Minor value to determine what beacon is that, connect to server and send user a notfication. The best would be if I could range and communicate with server in background. I used this sample to achieve background monitoring: https://altbeacon.github.io/android-beacon-library/samples.html. I also downloaded sample project from here: https://github.com/AltBeacon/android-beacon-library-reference to base on it.

Unfortunately in this example when user enters the region Activity is launched... I don't want that to happen. Soo my question is: Is it possible to range beacons in background?

Also weird thing happens in my case beacause when I put my app in background method "didRangeBeaconsInRegion(Collection beacons, Region region)" is still called from MainActivity but no beacon is found. Also method is called less often because beaconManager is in background mode. When I launched sample project that was not happening. Maybe it's because I don't have monitoringActivity. My MainActivity does ranging instantly when launched. Of course I tried to setup everything exactly the same as it is in an example BeaconReferenceApplication.

BTW I'm testing my app on Nexus 5 with Android 6.0.1

Thank you in advance for any solutions!


回答1:


I finally figured it out how to do this! Actually I was quite simple and I was doing it right from the begining but by a mistake I'v been using old version of Altbeacon library and that caused all my problems... Ehh

Never mind. Here is my code. Meybe someone could use it ;) I made it by creating centralized Application class which implements BootstrapNotifier for background notifications when entering defined Region. My class also implements interfaces BeaconConsumer, RangeNotifier which are necessery to do beacon ranging.

package com.smartmachi.smartmachi_android;
import android.app.Application;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.os.RemoteException;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import org.altbeacon.beacon.Beacon;
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 java.util.Collection;

public class BeaconReferenceApplication extends Application implements BootstrapNotifier, BeaconConsumer, RangeNotifier {
    private static final String TAG = "BeaconReferenceApp";
    private RegionBootstrap regionBootstrap;
    private BackgroundPowerSaver backgroundPowerSaver;
    private MainActivity rangingActivity = null;
    BeaconManager beaconManager;


    public void onCreate() {
        super.onCreate();
        beaconManager = BeaconManager.getInstanceForApplication(this);
        beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19"));

        Region region = new Region("backgroundRegion", Identifier.parse("0xf7826da6bc5b71e0893e"), null, null);
        regionBootstrap = new RegionBootstrap(this, region);

        backgroundPowerSaver = new BackgroundPowerSaver(this);

        beaconManager.setBackgroundBetweenScanPeriod(30000l);
        beaconManager.setForegroundBetweenScanPeriod(2000l);
        beaconManager.bind(this);
    }

    @Override
    public void didEnterRegion(Region region) {
        Log.d(TAG, "did enter region.");
        try {
            beaconManager.startRangingBeaconsInRegion(region);
        }
        catch (RemoteException e) {
            if (BuildConfig.DEBUG) Log.d(TAG, "Can't start ranging");
        }
    }

    @Override
    public void didExitRegion(Region region) {
        try {
            beaconManager.stopRangingBeaconsInRegion(region);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void didDetermineStateForRegion(int state, Region region) {
        Log.d(TAG,"I have just switched from seeing/not seeing beacons: " + state);
    }

    private void sendNotification(String text) {
        NotificationCompat.Builder builder =
                new NotificationCompat.Builder(this)
                        .setContentTitle("Beacon Reference Application")
                        .setContentText(text)
                        .setSmallIcon(R.drawable.ic_launcher);

        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        stackBuilder.addNextIntent(new Intent(this, MainActivity.class));
        PendingIntent resultPendingIntent =
                stackBuilder.getPendingIntent(
                        0,
                        PendingIntent.FLAG_UPDATE_CURRENT
                );
        builder.setContentIntent(resultPendingIntent);
        NotificationManager notificationManager =
                (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(1, builder.build());
    }

    @Override
    public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
        if (beacons.size() > 0) {
            for (Beacon b : beacons) {
                if(b.getId2().toString().equals("0x6d767674636e")) {
                    Log.e(TAG, "Beacon with my Instance ID found!");
                    sendNotification("Beacon with my Instance ID found!");
                }
            }
        }
    }

    @Override
    public void onBeaconServiceConnect() {
        beaconManager.setRangeNotifier(this);
    }
}


来源:https://stackoverflow.com/questions/36063992/how-to-range-beacons-in-background-using-altbeacon-android-beacon-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!