博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android蓝牙4.0(BLE)开发之ibeacon初步
阅读量:5904 次
发布时间:2019-06-19

本文共 6893 字,大约阅读时间需要 22 分钟。

此文使用的ibeacon模块是april beacon。至于什么是ibeacon。本文不做解释,详细请自查。

一个april beacon里携带的信息例如以下

0201061AFF4C0002159069BDB88C11416BAC3F33468C2788A3044B0378C60C09417072696C426561636F6E051250002003020A0000000000000000000000

详细是什么意思呢

02  Number of bytes that follow in first AD structure01  Flags AD type06     Flags value 0x1A = 000011010       bit 0 (OFF) LE Limited Discoverable Mode       bit 1 (ON) LE General Discoverable Mode       bit 2 (OFF) BR/EDR Not Supported       bit 3 (ON) Simultaneous LE and BR/EDR to Same Device Capable (controller)       bit 4 (ON) Simultaneous LE and BR/EDR to Same Device Capable (Host)1a Number of bytes that follow in second (and last) AD structure前面是常规智能硬件广播包部分ff (FF代表后面是Manufacture Data)4c 00   (组织标识,0x4c00苹果公司标识,https://www.bluetooth.org/en-us/specification/assigned-numbers/company-identifiers)02 (0x02 ibeacon标识位)15 (0x15,22个字节标识长度,uuid,major。minor总和的长度)90 69 bd b8-8c 11-41 6b-ac 3f-33 46 8c 27 88 a3 (Proximity UUID)04 4b(1099,major)03 78(888,minor)c6  (切记这里是补码,转化为原码就是-58,iBeacon的信号发出强度值。用来作为和RSSI一起測距的基准 ,txPower)        计算            C6            1100 0110 补码            1100 0101 反码            1011 1010 原码            -(32+16+8+2)            -580c09    (未知)417072696c426561636f6e(AprilBeacon字符串相应的十六进制)051250002003020a0000000000000000000000(未知)

Proximity UUID :这是将你全部的beacon与其他人的beacon设备差别开的id!比如,眼下在商店里某个区域分布着多个beacon形成一条“链带”,用于为顾客提供特定的服务,那么归属于同一条“链带”的beacon将分配到同样的proximity UUID。

为这条“链带”设计的专用应用程序将会在后台使用这个UUID扫描到这条“链带”中的beacon设备。

major 编号:用于将相关的beacon标识为一组。比如,一个商店中的全部beacon将会分配到同样的major编号。

通过这样的方式,应用程序就能够知道顾客位于哪一家商店。

minor 标号:用于标识特定的beacon设备。比如一个商店中的每个beacon设备都拥有唯一的minor编号。这样你才干够知道顾客位于商店中的哪个位置。

Measuring distance(測量距离)

最后一个值。 TX power ,用于确定你和beacon之间距离有多近。依据这个值不但能够获得粗略的信息(比方靠近/远离/不在范围内等)。也能够获取精确到米的距离(当然你也能够转换为以步为单位的距离)。

那么怎样实现?

TX power (上面样例中为0xC6=198,依据2的补码測得256-198=-58dBm)是距离设备1米測得的信号强度值(RSSI- Received Signal Strength Indication。接收到的信号强弱指标)。假如接收到的信号强度减弱了,那么我们可能在远离。仅仅要知道1米距离的RSSI。以及当前的RSSI(我们能够从接收到的信号中一块获取到这些信息),那么计算出当前的距离是可能的。IOS已经实现了个这个功能,对于其他平台须要自己手动编码计算 。

一个简单的測距函数

protected static double calculateAccuracy(int txPower, double rssi) {        if (rssi == 0) {            return -1.0; // if we cannot determine accuracy, return -1.        }        double ratio = rssi * 1.0 / txPower;        if (ratio < 1.0) {            return Math.pow(ratio, 10);        } else {            double accuracy = (0.89976) * Math.pow(ratio, 7.7095) + 0.111;            return accuracy;        }    }

在使用蓝牙时须要加权限

关键代码例如以下

package cn.edu.zafu.ble;import android.app.Activity;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothDevice;import android.bluetooth.BluetoothManager;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.util.Log;public class MainActivity extends Activity {
private BluetoothAdapter mBluetoothAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter(); if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { Intent enableBluetooth = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBluetooth, 1); } mBluetoothAdapter.startLeScan(mLeScanCallback); } private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) { int startByte = 2; boolean patternFound = false; // 寻找ibeacon while (startByte <= 5) { if (((int) scanRecord[startByte + 2] & 0xff) == 0x02 && // Identifies // an // iBeacon ((int) scanRecord[startByte + 3] & 0xff) == 0x15) { // Identifies // correct // data // length patternFound = true; break; } startByte++; } // 假设找到了的话 if (patternFound) { // 转换为16进制 byte[] uuidBytes = new byte[16]; System.arraycopy(scanRecord, startByte + 4, uuidBytes, 0, 16); String hexString = bytesToHex(uuidBytes); // ibeacon的UUID值 String uuid = hexString.substring(0, 8) + "-" + hexString.substring(8, 12) + "-" + hexString.substring(12, 16) + "-" + hexString.substring(16, 20) + "-" + hexString.substring(20, 32); // ibeacon的Major值 int major = (scanRecord[startByte + 20] & 0xff) * 0x100 + (scanRecord[startByte + 21] & 0xff); // ibeacon的Minor值 int minor = (scanRecord[startByte + 22] & 0xff) * 0x100 + (scanRecord[startByte + 23] & 0xff); String ibeaconName = device.getName(); String mac = device.getAddress(); int txPower = (scanRecord[startByte + 24]); Log.d("BLE",bytesToHex(scanRecord)); Log.d("BLE", "Name:" + ibeaconName + "\nMac:" + mac + " \nUUID:" + uuid + "\nMajor:" + major + "\nMinor:" + minor + "\nTxPower:" + txPower + "\nrssi:" + rssi); Log.d("BLE","distance:"+calculateAccuracy(txPower,rssi)); } } }; static final char[] hexArray = "0123456789ABCDEF".toCharArray(); private static String bytesToHex(byte[] bytes) { char[] hexChars = new char[bytes.length * 2]; for (int j = 0; j < bytes.length; j++) { int v = bytes[j] & 0xFF; hexChars[j * 2] = hexArray[v >>> 4]; hexChars[j * 2 + 1] = hexArray[v & 0x0F]; } return new String(hexChars); } protected static double calculateAccuracy(int txPower, double rssi) { if (rssi == 0) { return -1.0; // if we cannot determine accuracy, return -1. } double ratio = rssi * 1.0 / txPower; if (ratio < 1.0) { return Math.pow(ratio, 10); } else { double accuracy = (0.89976) * Math.pow(ratio, 7.7095) + 0.111; return accuracy; } }}

至此,本文也就结束,所谓初步,就是获取ibeacon模块的基本信息。

源代码下载

转载地址:http://mmkpx.baihongyu.com/

你可能感兴趣的文章
Java反射与hook混用反射某支付的方法
查看>>
Android 安卓手机及平板虚拟键盘遮住底部导航栏问题
查看>>
前端性能优化 - Resource Hints 资源预加载
查看>>
QPM 准备优化前的思考
查看>>
JavaScript-console的使用_016
查看>>
两种方式设置iframe的高度区别
查看>>
应用后台省电秘籍——低功耗状态下应用如何正常运行?
查看>>
Iterator 和 for...of 循环
查看>>
PAT A1086
查看>>
浅析微信支付:开发前的准备
查看>>
我理解的数据结构(七)—— 堆和优先队列(Heap And PriorityQueue)
查看>>
Category 特性在 iOS 组件化中的应用与管控
查看>>
python模块之shutil
查看>>
浮动的label
查看>>
前端工程化
查看>>
微信公众号开发中的支付流程
查看>>
PowerShell 学习笔记 - 1 PS Core 基础
查看>>
NodeJS+Express搭建个人博客-环境搭建(一)
查看>>
关于iOS 11.x微信连wifi流程中,在Portal页无法拉起微信问题的简单记录
查看>>
Golang Gin实践 番外 请入门 Makefile
查看>>