android蓝牙4.0(BLE)开发之ibeacon初步
Posted brave-sailor
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android蓝牙4.0(BLE)开发之ibeacon初步相关的知识,希望对你有一定的参考价值。
一个april beacon里携带的信息如下
1
|
<code class = " hljs " >0201061AFF4C0002159069BDB88C11416BAC3F33468C2788A3044B0378C60C09417072696C426561636F6E051250002003020A0000000000000000000000</code> |
具体是什么意思呢
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
<code class = " hljs vhdl" > 02 Number of bytes that follow in first AD structure 01 Flags AD type 06 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 ) - 58 0c09 (未知) 417072696c426561636f6e(AprilBeacon字符串对应的十六进制) 051250002003020a0000000000000000000000(未知) </code> |
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已经实现了个这个功能,对于其它平台需要自己手动编码计算 。
一个简单的测距函数
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<code class = "language-java hljs " > 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; } }</code> |
在使用蓝牙时需要加权限
1
2
3
4
|
<uses-permission android:name= "android.permission.BLUETOOTH_ADMIN" > <uses-permission android:name= "android.permission.RECEIVE_BOOT_COMPLETED" > </uses-permission></uses-permission></uses-permission></code> |
关键代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
<code class = "language-java hljs " > 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; } } } </code> |
至此,本文也就结束,所谓初步,就是获取ibeacon模块的基本信息。
源码下载
http://download.csdn.net/detail/sbsujjbcy/8503507
以上是关于android蓝牙4.0(BLE)开发之ibeacon初步的主要内容,如果未能解决你的问题,请参考以下文章