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

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

一个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
<code
class
=
"language-xml hljs "
> <uses-permission android:name=
"android.permission.BLUETOOTH"
>
    
<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

转载于:https://www.cnblogs.com/Free-Thinker/p/5560433.html

你可能感兴趣的文章
python 配置github项目配置
查看>>
copy()之绝版应用
查看>>
sparksql
查看>>
软件工程概论 - 个人总结
查看>>
数据库系统概论 中文高清PDF版下载
查看>>
bzoj3289: Mato的文件管理
查看>>
POJ 1995 Raising Modulo Numbers (快速幂取余)
查看>>
js this 引起的祸
查看>>
我是如何写作一本软件+哲学式的书籍的(下)
查看>>
用LSTM生成武侠人名
查看>>
深度学习在graph上的使用
查看>>
apt-get常用命令(转载)
查看>>
信安之星(iSecStar)U盘安全管理系统
查看>>
每天一个linux命令(32):gzip命令
查看>>
2018/12/08 L1-037 A除以B Java
查看>>
汤唯:在街头卖艺的那些日子
查看>>
进程,线程,主线程,异步
查看>>
SQL 中having 和where的区别分析
查看>>
Windows 平台安装 MongoDB
查看>>
字符串中判断存在的几种模式和效率(string.contains、string.IndexOf、Regex.Match)
查看>>