当前位置: 首页 > 编程日记 > 正文

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

相关文章:

APP程序内部打开某个APP的AppStore页面

作者 呀咪9527 关注 2017.03.21 16:44* 字数 222 阅读 154评论 0喜欢 9最近在做内购用到了StoreKit.framework库&#xff0c;偶然间发现中SKStoreProductViewController这个类&#xff0c;查看文档后发现一个妙用&#xff0c;解决了我一个痛点&#xff1a;APP每次更新或者跳转至…

sql server 2014预览版发布

MSDN发布sql server2014预览版&#xff0c;如下图&#xff1a; SQL Server 2014新特性&#xff1a; 微软SQL Server部门主管Eron Kelly介绍&#xff0c;通过将交易处理放到内存中进行&#xff0c;新的SQL Server 2014在测试中能够将性能提升50倍以上。在新版本中&#xff0c;DB…

数据通信技术(九:OSPF特殊区域配置(Cisco))

OSPF单区域配置实验(Cisco) 一&#xff0e;知识准备 1、掌握了OSPF动态路由协议的定义和功能&#xff1b; 2、掌握了OSPF动态路由协议的特征和工作原理。 二&#xff0e;实验目的 1、掌握路由器中OSPF特殊区域STUB配置方法和功能验证&#xff1b; 2、掌握OSPF特殊区域STUB…

iOS 屏幕亮度和闪光灯控制

所用涉及框架&#xff1a;AVFoundation框架和ImageIO 读取屏幕亮度&#xff1a;[UIScreen mainScreen].brightness; 设置屏幕亮度&#xff1a;[[UIScreen mainScreen] setBrightness:0.5]; 获取环境亮度主要代码&#xff1a; - (void)getTorch {AVCaptureDevice *device [AV…

一个几何不等式的最佳常数

今天上午动用win7旗舰版64位SP1(英特尔第二代酷睿I7-2630QM 2.00GHz 4核 内存 8G)下基于maple 16平台的BOTTEMA2009费时2899.02s,消耗内存633.56M,得到使不等式 $m_{a}w_{a}m_{b}w_{b}m_{c}w_{c}\leq k\cdot s^2$ 成立的最佳常数 $k$ 为如下一 $7$ 次方程 $729k^7-7599k^6-276…

数据通信技术(十:OSPF特殊区域TOTALLY STUB配置(ZTE))

OSPF特殊区域TOTALLY STUB配置(ZTE) 一&#xff0e;知识准备 1、掌握了OSPF动态路由协议的定义和功能&#xff1b; 2、掌握了OSPF动态路由协议的特征和工作原理。 二&#xff0e;实验目的 1、掌握路由器中OSPF特殊区域TOTAL STUB配置方法和功能验证&#xff1b; 2、掌握OS…

apue第四章习题的一些拙见(不定时更新)

写在前面:最近要期末考试&#xff0c;看来真的是要不定时更新啦XD apue4.1: 由于在这里lstat是不跟随符号文件的&#xff0c;而stat是跟随符号文件的&#xff0c;这样一来&#xff0c;如果使用stat&#xff0c;而不使用lstat那么就无法观察到符号文件。在书上4.3姐中有提到。 a…

容器使用之vector

出处&#xff1a;http://blog.csdn.net/edify/article/details/4035243 C内置的数组支持容器的机制&#xff0c;但是它不支持容器抽象的语义。要解决此问题我们自己实现这样的类。在标准C中&#xff0c;用容器向量&#xff08;vector&#xff09;实现。容器向量也是一个类模板。…

Hyperloop 让发布简洁高效

原文链接&#xff1a;https://mp.weixin.qq.com/s/MZMqzaKLqQN0zJikNYEbwgHyperloop 是服务于美团点评客户端的组件发版、持续集成、App 打包构建、资源调度等各个环节的发布调度系统。名称起源于美国 Elon Musk 构想的 Hyperloop 超级高铁&#xff0c;象征着现代、简洁、高效。…

数据通信技术(十一:无中继的DHCP配置(ZTE))

路由器的无中继DHCP配置(ZTE) 一&#xff0e;知识准备 1、掌握DHCP的基本原理和作用&#xff1b; 2、掌握DHCP的网络架构。 二&#xff0e;实验目的 1、掌握中兴路由器DHCP的配置方法和功能验证&#xff1b; 三&#xff0e;实验内容 1、完成中兴路由器DHCP的基本配置和结…

小米4手机在DDMS下获取data/data目录权限

1.首先先root手机 2.进入adb adb shell su //获取root权限 mount -0 remount,rw /data //重新挂载分区为可读写(可以用 df命令查看分区情况) chmod 777 /data //更改文件夹权限可读写 3.adb 常用命令大全 1. 显示系统中全部Android平台&#xff1a; android list targets 2. 显…

工程大小优化之图片资源

工程大小优化之图片资源 摘要&#xff1a;点点iOS项目本身功能较多&#xff0c;导致应用体积也比较大。一个Xcode工程下图片资源占用了很大的空间&#xff0c;且如果有些App需要一键换肤功能&#xff0c;呵呵&#xff0c;不知道得做多少图片。每套图片还需要设置1x,2x,3x等 简介…

鼠标悬浮变手指

style"cursor:pointer" 转载于:https://www.cnblogs.com/dreamzcy/p/3200897.html

Spring Boot项目快速搭建

实验要求及目的&#xff1a; &#xff08;1&#xff09;掌握ApplicationContext容器使用属性setter方法注入的实现&#xff1b; &#xff08;2&#xff09;了解Spring的概念和优点&#xff1b; &#xff08;3&#xff09;熟悉Spring中的IOC和DI&#xff1b; 实验环境&#xff1…

wcf入门教程

一、概述 Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口&#xff0c;可以翻译为Windows通讯接口&#xff0c;它是.NET框架的一部分。由 .NET Framework 3.0 开始引入。 WCF的最终目标是通过进程或不同的系统、通过本地网络或是通过Inter…

Swift iOS : 字体图标

厌倦了使用位图在xcode的Assets.xcassets内&#xff0c;因为麻烦&#xff0c;包括如下的麻烦&#xff1a; 找图图需要分尺寸需要操作员类似工作去管理 然后&#xff0c;现在有了字体图标&#xff0c;就方便多了&#xff1a; 比较成熟的几套库&#xff0c;用名字就可以查矢量…

巧用Excel 2010数据透视表制作销售报表

小刘需要根据2010-2011两年间的订单记录创建季度报表&#xff0c;以便分析各类图书的销售情况。面对如此庞大的订单记录&#xff0c;该从何下手呢? 其实最快捷的办法是使用Excel 2010创建数据透视表&#xff0c;以快速合并和比较这些数据。在数据透视表中&#xff0c;可以很清…

Spring的基础应用

实验目的及要求 掌握ApplicationContext容器使用属性setter方法注入的实现&#xff1b;了解Spring的概念和优点&#xff1b; 熟悉Spring中的IOC和DI 实验环境 Java jdk 1.8&#xff1b;apache-maven-3.6.0&#xff1b;Myeclipse C10&#xff1b; 实验内容&#xff1a; 任务一…

iOS App 连接外设的几种方式

原创作者: Max_Marry 文章地址: http://www.jianshu.com/p/852bf92c5c92 随着近年来车联网和物联网的兴起&#xff0c;智能家居和智能硬件的逐步火热&#xff0c;越来越多的 App 被用来跟硬件设备进行来连接&#xff0c;获取硬件相关信息用以展示或者发送指令控制硬件来提供服务…

Android深度探索(卷1)HAL与驱动开发第五章总结

开发板是开发和学习嵌入式技术的主要硬件设备&#xff0c;开发板的型号和种类很多&#xff0c;目前流行的是基于S3C6410 ARM11架构的开发板&#xff0c;S3C6410是由三星公司推出的一款低功耗&#xff0c;高性价比的RISC处理器&#xff0c;它基于ARM11内核&#xff0c;可广泛应用…

controlfile

1、如何恢复控制文件 Your database instance is started using the server parameter file (SPFILE). Control files are multiplexed and stored on different disks. Because of a disk failure, you lost one of these control files. You replaced the damaged disk. What…

Spring servlet

1、修改pom.xml文件&#xff0c;添加以下内容&#xff1a; 代码&#xff1a; <dependency><groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> <dependency> <groupId>org.apac…

iOS传感器:实现一个随屏幕旋转的图片

作者 非典型技术宅 关注 2017.05.24 17:22* 字数 1568 阅读 351评论 7喜欢 14在写上一个动画系列的时候学到了非常多的知识&#xff0c;也认识了很多人。例如受邀进入了某个神秘的动效组织&#xff0c;全是一线的大神啊。有UI的大牛、UED的大神、iOS的大神。加入组织可以阅读这…

构建之法-读后感

大二快结束&#xff0c;从大二初开始接触项目的工程开发&#xff0c;到现在也差不多一年了。之前一直在用c# 结合winform开发一些简单的桌面应用&#xff0c;也看过一些是实验室学长们用c#和其他多种技术结合 开发出来的系统&#xff0c; 接触过其源代码&#xff0c;为深入了解…

Java 理论与实践: 非阻塞算法简介——看吧,没有锁定!(转载)

简介&#xff1a; Java™ 5.0 第一次让使用 Java 语言开发非阻塞算法成为可能&#xff0c;java.util.concurrent 包充分地利用了这个功能。非阻塞算法属于并发算法&#xff0c;它们可以安全地派生它们的线程&#xff0c;不通过锁定派生&#xff0c;而是通过低级的原子性的硬件原…

pring Boot与MyBatista的集成

1、准备数据库环境&#xff0c;在MySQL数据库中&#xff0c;创建一个名为microservice的数据库&#xff0c;在microservice中创建表tb_user&#xff0c;并在表中插入3条数据&#xff1b; 2、创建项目&#xff0c;添加依赖。 3、编写配置文件&#xff0c;在application.properti…

iOS中UIDynamic物理仿真详解

本文中所有代码演示均有GitHub源码&#xff0c;点击下载 UIDynamic简介 简介&#xff1a; UIKit动力学最大的特点是将现实世界动力驱动的动画引入了UIKit&#xff0c;比如动力&#xff0c;铰链连接&#xff0c;碰撞&#xff0c;悬挂等效果&#xff0c;即将2D物理引擎引入了UIKi…

ADO与ADO.NET的区别与介绍

1. ADO与ADO.NET简介ADO与ADO.NET既有相似也有区别&#xff0c;他们都能够编写对数据库服务器中的数据进行访问和操作的应用程序&#xff0c;并且易于使用、高速度、低内存支出和占用磁盘空间较少&#xff0c;支持用于建立基于客户端/服务器和 Web 的应用程序的主要功能。但是A…

cucumber 文件目录结构和执行顺序

引用链接&#xff1a;http://www.cnblogs.com/timsheng/archive/2012/12/10/2812164.html Cucumber是Ruby世界的BDD框架&#xff0c;开发人员主要与两类文件打交 到&#xff0c;Feature文件和相应的Step文件。Feature文件是以 feature为后缀名的文件&#xff0c;以Given-When-T…

Spring Boot与Redis的集成

1、在Linux中安装Redis。 1.1、在线下载软件 1.2、安装软件 1.3、修改配置文件 1.4、启动Redis&#xff1b; 2、添加Redis起步缓存&#xff0c;在pom.xml中添加Spring Boot支持Redis的依赖配置。 3、添加缓存注解。 3.1、在引导类Application.java中&#xff0c;添加EnableCac…