代码地址如下:
http://www.demodashi.com/demo/13390.html

与普通蓝牙相比,低功耗蓝牙显著降低了能量消耗,允许Android应用程序与具有更严格电源要求的BLE设备进行通信,如接近传感器、心率传感器等低功耗设备。

声明蓝牙权限

  和使用普通蓝牙一样,在使用低功耗蓝牙时也需要在AndroidManifest声明蓝牙权限,声明蓝牙权限的代码如下

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

如果想让你的App只适用于BLE设备,可以在AndroidManifest中继续添加以下代码

<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>

如果想让你的App适用于不支持BLE的设备,只需要将required="true"改为required="false"然后在代码中通过以下方法来判断设备是否支持BLE,

 private void checkIsSupportBLE() {
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
}

注:

LE信标往往与位置有关,如果想要通过``BluetoothLeScanner 方法来获取正确的扫描结果,需要在AndroidManifest中声明位置权限,声明位置权限可以使用ACCESS_COARSE_LOCATION或则 ACCESS_FINE_LOCATION` ,如过不声明位置权限,将不会返回蓝牙的扫描结果。

开启BLE

  开启BLE只需要以下两步

  1. 拿到BluetoothAdapter

    在Android系统中只有一个BluetoothAdapter,可以通过以下方法来获取

    private void obtainBluetoothAdapter() {
    final BluetoothManager bluetoothManager =
    (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    mBluetoothAdapter = bluetoothManager.getAdapter();
    }
  2. 开启蓝牙。

    通过isEnabled()可以判断是否已经开启BLE,如果没有开启则可以通过以下方法来开启

//注册广播接受者
private void initReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mReceiver, filter);
} //新建监听蓝牙状态变化的广播
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction(); if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
BluetoothAdapter.ERROR);
switch (state) {
case BluetoothAdapter.STATE_OFF:
mBluetoothState.setText("Bluetooth off");
break;
case BluetoothAdapter.STATE_TURNING_OFF:
mBluetoothState.setText("Turning Bluetooth off...");
break;
case BluetoothAdapter.STATE_ON:
mBluetoothState.setText("Bluetooth on");
break;
case BluetoothAdapter.STATE_TURNING_ON:
mBluetoothState.setText("Turning Bluetooth on...");
break;
}
}
}
};

此广播包含额外字段 EXTRA_STATEEXTRA_PREVIOUS_STATE,二者分别包含新的和旧的蓝牙状态。 这些额外字段可能的值包括 STATE_TURNING_ONSTATE_ONSTATE_TURNING_OFFSTATE_OFF。侦听此广播适用于检测在您的应用运行期间对蓝牙状态所做的更改。

扫描BLE设备

  扫描蓝牙设备可以通过 startLeScan(BluetoothAdapter.LeScanCallback)startLeScan(UUID[], BluetoothAdapter.LeScanCallback)方法,这两种扫描BLE设备的区别如下。

  • startLeScan(BluetoothAdapter.LeScanCallback)方法扫描的是周围所有的BLE设备。
  • startLeScan(UUID[], BluetoothAdapter.LeScanCallback)只扫描和UUID相匹配的设备。

可以发现无论通过哪种方式扫描蓝牙都必须要实现LeScanCallback回调方法,此方法是用来获取蓝牙扫描结果。

  通过以上两种方式实现扫描BLE设备的代码如下:

  1. 通过startLeScan(BluetoothAdapter.LeScanCallback)方法扫描蓝牙的代码如下

     //扫描BLE设备
    private void scanLeDevice(final boolean enable) {
    if (enable) {
    // Stops scanning after a pre-defined scan period.
    mHandler.postDelayed(new Runnable() {
    @Override
    public void run() {
    mScanning = false;
    mBluetoothAdapter.stopLeScan(mLeScanCallback);
    }
    }, SCAN_PERIOD); mScanning = true;
    mBluetoothAdapter.startLeScan(mLeScanCallback);
    } else {
    mScanning = false;
    mBluetoothAdapter.stopLeScan(mLeScanCallback);
    }
    } //扫描结果回调
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
    @Override
    public void onLeScan(final BluetoothDevice device, int rssi,
    byte[] scanRecord) {
    runOnUiThread(new Runnable() {
    @Override
    public void run() {
    mLeDeviceListAdapter.addDevice(device);
    mLeDeviceListAdapter.notifyDataSetChanged();
    }
    });
    }
    };
  2. 通过startLeScan(UUID[], BluetoothAdapter.LeScanCallback)方法扫描蓝牙的代码如下

    private void scanLeDeviceByUUID() {
    mBluetoothAdapter.startLeScan(new UUID[]{RX_SERVICE_UUID}, mLeScanCallback);
    }

    再次声明:

    LE信标往往与位置有关,如果想要通过BluetoothLeScanner 方法来获取正确的扫描结果,需要在AndroidManifest中声明位置权限,声明位置权限可以使用ACCESS_COARSE_LOCATION或则 ACCESS_FINE_LOCATION ,如过不声明位置权限,将不会返回蓝牙的扫描结果。

连接BLE设备

   要进行BLE设备之间的通讯,首先应该进行设备之间的连接,可以通过device.connectGatt (Context context,boolean autoConnect, BluetoothGattCallback callback)方法来连接设备。

  • autoConnect是设置当BLE设备可用时是否自动进行连接。
  • device就是通过扫描BLE设备获得的。
  • callback则是连接指定设备后的回掉,可以在回掉中知道是否建立连接、连接断开、以及获取设备之间传输的数据。

以下是BluetoothGattCallback类中具体的方法

下面我会介绍几个比较常用的方法:

  • onConnectionStateChange此方法的作用是可以获得设备连接的状态,如“成功连接”、“断开连接”。
  • onServicesDiscovered当远程设备的服务,特性和描述符列表已更新时(即发现新服务),调用此方法。
  • onCharacteristicChanged远程特征变化会调用此方法,即BLE设备的状态发生了变化会调用此方法。

onCharacteristicChanged方法就是相当于BLE设备对你操作的回应,如打开BLE设备成功等,然后在此方法回掉之后,便可以继续下一步操作了。

操作BLE设备

  在设备连接之后,就可以向BLE设备发送命令来操作BLE设备了,向BLE写数据的代码如下

public boolean writeByteToBleDevice(byte[] data) {
BluetoothGattService mBluetoothGattService = mBluetoothGatt.getService(RX_SERVICE_UUID);
if (mBluetoothGattService == null) {
return false;
} BluetoothGattCharacteristic characteristic = mBluetoothGattService.getCharacteristic(RX_SERVICE_UUID);
if (characteristic == null) { return false;
} boolean b = characteristic.setValue(data); return b && mBluetoothGatt.writeCharacteristic(characteristic);
}

在向BLE设备发送数据之后,就可以在onCharacteristicChanged方法中获得BLE设备的状态了。

项目结构

项目代码结构图截图

结束语

  这篇文章拖了这么久,总算写完了,本来打算在上一篇蓝牙文章写完后就写这篇,结果中间公司忙着上线新的项目,加班加点将近一个月,就没时间写这篇文章了,在项目上线之后就立马开始写这篇文章,希望这篇文章能帮到想要学习蓝牙的朋友。

Android低功耗蓝牙(BLE)使用详解

代码地址如下:
http://www.demodashi.com/demo/13390.html

注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

Android低功耗蓝牙(BLE)使用详解的更多相关文章

  1. 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发具体解释

    转载请注明来源: http://blog.csdn.net/kjunchen/article/details/50909410 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发具体 ...

  2. Android低功耗蓝牙(BLE)开发的一点感受

    最近一段时间,因为产品的需要我做了一个基于低功耗蓝牙设备的Android应用,其中碰到了一些困难,使我深深体会到Android开发的难处:不同品牌,不同型号和不同版本之间的差异使得Android应用适 ...

  3. Android 低功耗蓝牙BLE 开发注意事项

    基本概念和问题 1.蓝牙设计范式? 当手机通过扫描低功耗蓝牙设备并连接上后,手机与蓝牙设备构成了客户端-服务端架构.手机通过连接蓝牙设备,可以读取蓝牙设备上的信息.手机就是客户端,蓝牙设备是服务端. ...

  4. Android低功耗蓝牙(蓝牙4.0)——BLE开发(上)

    段时间,公司项目用到了手机APP和蓝牙设备的通讯开发,这里也正好对低功耗蓝牙(蓝牙4.0及以后标准)的开发,做一个总结. 蓝牙技术联盟在2010年6月30号公布了蓝牙4.0标准,4.0标准在蓝牙3.0 ...

  5. 深入浅出讲解低功耗蓝牙(BLE)协议栈

    详解BLE连接建立过程https://www.cnblogs.com/iini/p/8972635.html 详解BLE 空中包格式—兼BLE Link layer协议解析https://www.cn ...

  6. 【转】Android低功耗蓝牙应用开发获取的服务UUID

    原文网址:http://blog.csdn.net/zhangjs0322/article/details/39048939 Android低功耗蓝牙应用程序开始时获取到的蓝牙血压计所有服务的UUID ...

  7. 低功耗蓝牙BLE外围模式(peripheral)-使用BLE作为服务端

    低功耗蓝牙BLE外围模式(peripheral)-使用BLE作为服务端 Android对外模模式(peripheral)的支持 从Android5.0开始才支持 关键术语和概念 以下是关键BLE术语和 ...

  8. Android高效率编码-第三方SDK详解系列(一)——百度地图,绘制,覆盖物,导航,定位,细腻分解!

    Android高效率编码-第三方SDK详解系列(一)--百度地图,绘制,覆盖物,导航,定位,细腻分解! 这是一个系列,但是我也不确定具体会更新多少期,最近很忙,主要还是效率的问题,所以一些有效的东西还 ...

  9. Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)

    Android XML shape 标签使用详解   一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...

随机推荐

  1. 解决phpStudy启动网站警告问题

    在用phpStudy的时候,在页面中会有一些警告 notice:Undefined variable... notice:Undefined index... 在php.ini里面找到 display ...

  2. 初雪-Diary?

    who care ------------2018 11 6-------------- 终于AK一场啦 ------------2018 10 18-------------- 嗯....今天T2多 ...

  3. 【动态规划】CDOJ1692 这是一道比CCCC简单题更有想象力的中档题

    f(i,j)表示打了i行出现j个bug的方案数. 还是跟背包有点像嘛. #include<cstdio> using namespace std; int n,m,b,mod,a[510] ...

  4. 【深度搜索+剪枝】POJ2362-Square

    从昨天晚上写到现在,一直在TLE,现在终于剪枝完成了_(:зゝ∠)_ [思路] 深搜:用这类型组合题目最基本的深搜,变量side记录当成已经组成了几条变,sl表示当前在组合的边已经有的长度.如果当前s ...

  5. fedora19/opensuse13.1 配置svn client

    Date: 20140208Auth: Jin 一.install zypper install  subversion yum install  subversion 二.操作 1.将文件check ...

  6. [典型漏洞分享]YS忘记密码机制设计存在缺陷,导致任意用户口令均可被修改【高】

    记录了安全测试过程中发现的一些典型的安全问题 YS忘记密码机制存在缺陷,可导致任意用户口令被修改[高] 问题描述: YS网站提供用户密码修改功能,当用户忘记密码时可通过该功能找回密码,但该修改密码的流 ...

  7. arcgis10.2转shp文件中文乱码问题解决方案

    从ArcGIS的数据源入手,自己升级ArcGIS for Desktop到10.2.0,然后用该版本ArcGIS软件重新导出数据,竟然还是乱码.经咨询ArcGIS技术支持,技术支持说必须保证shp文件 ...

  8. Android-25种开源炫酷动画框架

    前言 忙碌的工作终于可以停息一段时间了,最近突然有一个想法,就是自己写一个app,所以找了一些合适开源控件,这样更加省时,再此分享给大家,希望能对大家有帮助,此博文介绍的都是UI上面的框架,接下来会有 ...

  9. OCP升级(3.6->3.7)

    有个好文档还是靠普很多,感谢同事的文档.升级步骤记录如下 1.检查现有环境 [root@master ~]# etcd --version etcd Version: Git SHA: 1674e68 ...

  10. sql server阻塞(block)处理

    sp_who2 ACTIVE --从下图可知spid = 65进程被76阻塞 --或 * FROM sys.sysprocesses WHERE blocked <> 0 ) --查看阻塞 ...