【Android iBeacon室内定位】Android Beacon Library之进入离开beacon区域和提高搜索结果稳定性

本文详细介绍了如何使用Android Beacon Library来判断用户进入和离开iBeacon区域,以及如何解决搜索结果的不稳定性问题。通过在Service中进行后台搜索,并利用EventBus进行信息交互,实现了更准确的区域判断和稳定性优化。文章提供了具体的代码示例和运行效果分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.概要

上一篇我们已经实现了室内定位的简单功能,接下来我们来实现怎么判断进入区域和离开区域,其实现原理也十分简单,进入区域的功能添加一个变量来进行判断就可以了,离开区域则可以根据连续搜索到的结果来进行判断,比如连续10次都搜不到我们需要的beacon标签我们则判断已经离开区域了,具体次数可以根据需求做调整,最好不要在5次以内,因为有的安卓手机搜索确实不是很稳定,有时候周围明明有很多标签,但搜到的标签个数还是为0,就可能产生错误的判断,但一般这种情况都是很快就会继续搜到标签;

刚才已经说了,安卓手机搜索不稳定,所以很有可能你搜到了离你比较近的beacon1,但有时候会蹦到beacon2或者beacon3等其他beacon标签去,然后又回到beacon1,这种用户体验是十分不好的,所以如果想搜索结果与实际出入不那么大,我们还需要做一些判断,来解决这个问题

所以这篇文章总得来说解决以下几个问题:

1.判断用户进入区域

2.判断用户离开区域

3.解决搜索不稳定的问题


2.修改

我们先把上一篇的代码修改一下,将前台搜索改成后台搜索,将MainActivity里面的beacon搜索功能挪到一个service里面去,使用EventBus让activity与service进行信息交互。先导入eventbus的库

compile 'org.greenrobot:eventbus:3.0.0'

在数据里多添加一个标签信息进行对比切换

public class BeaconLocationData {

    public  Map<String, Map<String, String>> locations =new HashMap<>();

    public BeaconLocationData() {
        initLocationData();
    }

    private void initLocationData() {
        Map<String, String> minorLocations = new HashMap<>();
        minorLocations.put("16101", "A栋 6层");
        minorLocations.put("17101", "A栋 7层");
        minorLocations.put("10101", "A栋 1层");
        locations.put("10001", minorLocations);
    }

    public String getLocationMsg(String major, String minor) {
        String location;
//        location = locations.get(major).get(minor);
        Map<String,String> minorMap = locations.get(major);
        if (minorMap == null || minorMap.size() == 0) {
            return "暂无位置信息";
        }
        location = minorMap.get(minor);
        if (location == null || location.equals("")) {
            return "暂无位置信息";
        }
        return location;
    }
    
}

下面直接贴出MainAcitivty和service(即MyBeaconService)类的代码


public class MainActivity extends AppCompatActivity{

    private static final String TAG = "MainActivity";
    private TextView tvLocationMsg;

    private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        requestLocationPermissions();
        EventBus.getDefault().register(this);
    }

    private void requestLocationPermissions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            // Android M Permission check
            if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

                final AlertDialog.Builder builder = new AlertDialog.Builder(this);

                builder.setTitle("This app needs location access");
                builder.setMessage("Please grant location access so this app can detect beacons.");
                builder.setPositiveButton(android.R.string.ok, null);

                builder.setOnDismissListener(new DialogInterface.OnDismissListener() {

                    @TargetApi(Build.VERSION_CODES.M)
                    @Override
                    public void onDismiss(DialogInterface dialog) {
                        requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
                    }
                });

                builder.show();

            }

        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_COARSE_LOCATION: {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG, "coarse location permission granted");
                } else {
                    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                    builder.setTitle("Functionality limited");
                    builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
                    builder.setPositiveButton(android.R.string.ok, null);
                    builder.setOnDismissListener(new DialogInterface.OnDismissListener() {

                        @Override
                        public void onDismiss(DialogInterface dialog) {
                        }

                    });
                    builder.show();
                }
                return;
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        MyBeaconService.startMyBeaconService(this);
    }

    private void initView() {
        tvLocationMsg = (TextView) findViewById(R.id.tv_location_msg);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void eventBussCallBack(String location) {
        tvLocationMsg.setText(location);
    }

    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        MyBeaconService.stopMyBeaconService(this);
    }
}

 


public class MyBeaconService extends Service implements BeaconConsumer {

    private static final long DEFAULT_FOREGROUND_SCAN_PERIOD = 1000L;
    private static final long DEFAULT_FOREGROUND_BETWEEN_SCAN_PERIOD = 1000L;
    private static final String TAG = "MyBeaconService";
    private BeaconManager beaconManager;
    /** 重新调整格式*/
    public static final String IBEACON_FORMAT = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24";
    /** 设置兴趣UUID*/
    public static final String FILTER_UUID = "FDA50693-A4E2-4FB1-AFCF-C6EB07647825";
    public BeaconLocationData beaconLocationData;
    private Region region;

    @Nullable
    @Override
    public IBinder onBind(Intent
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值