一个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

android蓝牙4.0(BLE)开发之ibeacon初步的更多相关文章

  1. Android 蓝牙4.0 BLE

    Android ble (Bluetooth Low Energy) 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才可以使用. BLE是蓝牙4.0的核心Profil ...

  2. Android 蓝牙4.0 BLE (onServicesDiscovered 返回 status 是 129,133时)

    Android ble (Bluetooth Low Energy) 蓝牙4.0,也就是说android 4.3+, API level >= 18,且支持蓝牙4.0的手机才可以使用. BLE是 ...

  3. ym——物联网入口之中的一个Android蓝牙4.0

    转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! 假设还有同学不知道蓝牙4.0能够做什么请查看Android+蓝牙 4.0 将带来什么? ...

  4. android 蓝牙4.0 开发介绍

    最近一直在研究一个蓝牙功能 由于本人是菜鸟  学起来比较忙 一直搞了好久才弄懂 , 网上对蓝牙4.0也就是几个个dome 抄来抄去,全是英文注解 , 对英语不好的朋友来说 真是硬伤 , 一些没必要的描 ...

  5. iPhone开发之UIScrollView初步

    来源:http://blog.csdn.net/htttw/article/details/7891396 iPhone开发之UIScrollView初步 今天我们初步介绍以一下iPhone开发中的U ...

  6. Android BLE开发之Android手机与BLE终端通信

    本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处! 近期穿戴设备发展得非常火.把相关技术也带旺了,当中一项是BLE(Bluetooth Low Energy).B ...

  7. Android项目实战(三十四):蓝牙4.0 BLE 多设备连接

    最近项目有个需求,手机设备连接多个蓝牙4.0 设备 并获取这些设备的数据. 查询了很多资料终于实现,现进行总结. ------------------------------------------- ...

  8. IOS学习之蓝牙4.0 BLE

    IOS学习也一段时间了,该上点干货了.前段时间研究了一下IOS蓝牙通讯相关的东西,把研究的一个成果给大家分享一下. 一 项目背景 简单介绍一下做的东西,设备是一个金融刷卡器,通过蓝牙与iphone手机 ...

  9. Android 蓝牙4.0的连接和通讯

    1.加入权限 <uses-sdk android:minSdkVersion=" android:targetSdkVersion="/> <uses-featu ...

随机推荐

  1. 浅谈dataGridView使用,以及画面布局使用属性,对datagridview进行增删改查操作,以及委托使用技巧

        通过几天的努力后,对datagridview使用作一些简要的介绍,该实例主要运用与通过对datagridview操作.对数据进行增删改查操作时,进行逻辑判断执行相关操作.简单的使用委托功能,实 ...

  2. VB.NET中LINQ TO List泛型查询语句(分组,聚合函数)

    Public Class LinqToList 'LINQ在C#中使用比较方便,但是在VB中使用比较麻烦,复杂,和C#用法并不太一样 Dim listNew As List(Of Product) = ...

  3. 使用Raphael 画图(四) 路径(一) (javascript)

    这章介绍路径,本人觉得这是比较难和精髓的一部分. 先介绍基本知识: 可以参考: http://www.chinasvg.com/support/svg-tutorial/svg-path-direct ...

  4. C#【数据库】 Excel打开到DataGridView

    if (openFileDialog1.ShowDialog() == DialogResult.OK) { Filename = openFileDialog1.FileName; string s ...

  5. 那些年被我坑过的Python——山外有山(第四章)

    装饰器: 定义: 本质是函数,(装饰其他函数)就是为其他函数添加附加功能原则: 1.不能修改被装饰的函数的源代码 2.不能修改被装饰的函数的调用方式 优点: 装饰器带来的最直观的好处:减少对函数的细化 ...

  6. Execl DataTime Format Number

    Excel 中日期类型所保存的值是数值型.只是设置了为日期格式,通过公式转换从而得出我们平时常用的日期内容.也很好理解这公式所要说明的意思.数值是个浮点型可以分成2部分看.整数部分:年月日(日期)小数 ...

  7. HTML部分标签的含义(2)

    1,ul标签,添加新闻信息列表 使用ul标签,信息无先后顺序 这些列表就可以用ul-li标签来完成 语法:<ul> <li>信息</li> <li>信息 ...

  8. __block存储类型

    __block存储类型 你可以指定引入一个变量为可更改的,即读-写的,通过应用__block 存储类型修饰符.局部变量的__block 的存储和 register.auto.static 等存储类型相 ...

  9. HTML中如何添加日历插件(JQUERY)

    日期插件的包为:mydate.js1:首先将日期插件的包引入到页面中 1 <script language="JavaScript" src="../Inc/Js/ ...

  10. Oracle OCI-22053:溢出错误

    Oracle 数值数据类型最多可存储 38 个字节的精度.当将 Oracle 数值转换 为公共语言运行库数据类型时,小数点后边的位数可能过多,这会导致此错误.   查询29万笔数据,报此错误,分析应该 ...