当前位置: 首页 > 知识库问答 >
问题:

如何使用AltBeacon:Android Beacon库在后台定位信标?

于鹏
2023-03-14

我正在开发一个应用程序,提供后台信标监测。我想开始范围时,用户进入信标从定义的区域。当应用程序在后台,它一直在监控,用户进入我定义的区域,我想开始测距,并获得InstanceID或主要,次要值,以确定什么信标是,连接到服务器,并发送给用户一个通知。如果我能在后台与服务器通信,那就最好了。我使用以下示例实现后台监控:https://altbeacon.github.io/android-beacon-library/samples.html。我还从这里下载了示例项目:https://github.com/altbeacon/android-beacon-library-reference。

不幸的是,在本例中,当用户输入区域时,活动启动了······我不希望这种事发生。我的问题是:有可能在背景中测距信标吗?

同样奇怪的事情发生在我的beacause中,当我将应用程序放在后台时,方法“didrangeBeaconsinRegion(Collection beacons,Region Region)”仍然从MainActivity调用,但没有找到beacon。另外,由于beaconManager处于后台模式,因此调用方法的次数较少。当我启动示例项目时,这并没有发生。也许是因为我没有MonitoringActivity。我的主要活动在启动时立即测距。当然,我试图设置与BeaconReferenceApplication示例完全相同的所有内容。

顺便说一句,我正在Nexus 5上用Android6.0.1测试我的应用程序

提前感谢您提出的任何解决方案

共有1个答案

卫才
2023-03-14

我终于想通了怎么做到这一点!实际上我很简单,我从一开始就做得很好,但由于一个错误,我使用了旧版本的Altbeacon库,这导致了我所有的问题...呃

不要紧。这是我的代码。我创建了一个集中的应用程序类,它实现了BootstrapNotifier在进入定义区域时的后台通知。我的类还实现了接口BeaconConsumer和RangeNotifier,它们是用来进行信标测距的。

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);
    }
}
 类似资料:
  • 问题内容: 在下面的示例中,我在绿色背景上绘制了一个自定义,但是它没有出现。为什么会这样? 问题答案: JComponent不会绘制其背景。您可以自己绘制,也可以使用可以绘制背景的JPanel

  • 我试图创建一个应用程序扫描信标。前台应用程序工作得很好。然而,当我试图在应用程序中包含后台扫描时,它会导致应用程序崩溃。基本上,一旦应用程序启动,应用程序要求权限,关闭,后台扫描通知就会出现。所以,每次后台服务检测到一个信标,它就关闭应用程序。 我想做的是,当应用程序进入前台时,以某种方式停止后台扫描。我试着用 这是主要活动: 以下是日志:

  • 我的背景粘性服务是杀死奥利奥和更高的设备,任何解决方案,以获得位置的背景服务时,活动是在后台

  • 搜索到的配置都不管用,也没几个搜索词条。。。

  • 我正在努力为我的问题找到解决办法。问题是我试图在奥利奥中启动后台服务,以便检索位置。我看到了这一点:https://developer.android.com/about/versions/oreo/background-location-limits但我正在努力寻找解决办法。 当我启动Foreground服务时,我看到:(IllegalStateException:不允许启动服务)异常,因为我试

  • 我正在编写一个应用程序,需要高精度和低频率的背景位置更新。解决方案似乎是一个后台NSTimer任务,它启动location manager的更新,然后立即关闭。这个问题以前有人问过: 如何在iOS应用程序中每n分钟更新一次后台位置? 在应用程序进入后台后每n分钟获取一次用户位置 iOS不是典型的后台位置跟踪计时器问题 iOS长时间运行的后台计时器,具有“位置”后台模式 基于位置跟踪的iOS全职后台