android BLE 编程详解
来源:互联网 发布:淘宝卖家支付宝在哪里 编辑:程序博客网 时间:2024/05/16 19:06
最近可穿戴设备发展的很火,而且蓝牙4.0 以上支持低功耗模式,因此,android4.3(API18)以上支持蓝牙BLE编程。BLE是蓝牙4.0的核心Profile,主打功能是快速搜索,快速连接,超低功耗保持连接和传输数据,弱点是数据传输速率低,由于BLE的低功耗特点,因此普遍用于穿戴设备。下面介绍android 的BLE开发。
1. 基本概念介绍
- BluetoothManager :管理蓝牙服务的一个类,主要用于得到一个蓝牙适配器BluetoothAdapter。
- BluetoothAdapter类:代表了一个本地的蓝牙适配器。它是所有蓝牙交互的的入口点。利用它你可以发现其他蓝牙设备,查询绑定了的设备,使用已知的MAC地址实例化一个蓝牙设备和建立一个BluetoothServerSocket(作为服务器端)来监听来自其他设备的连接。
- BluetoothDevice类:代表了一个远端的蓝牙设备,使用它请求远端蓝牙设备连接或者获取远端蓝牙设备的名称、地址、种类和绑定状态。
- BluetoothGatt类:符合BLE GATT协议,封装了与其他蓝牙设备通信功能的一个类。可以通过BluetoothDevice的connectGatt(Context, boolean, BluetoothGattCallback)得到其实例。
- GATT(Generic Attribute Profile) 通用属性参数文件,通过BLE连接,读写属性类小数据的Profile通用规范。现在所有的BLE应用Profile都是基于GATT的。蓝牙 4.0特有。可以理解为一个规范文件。
- ATT(Attribute Protocol) 属性协议。GATT是基于ATTProtocol的。ATT针对BLE设备做了专门的优化,具体就是在传输过程中使用尽量少的数据。每个属性都有一个唯一的UUID,属性将以characteristics 和services的形式传输。
- Service 服务。Characteristic的集合。例如一个service叫做“Heart RateMonitor”,它可能包含多个Characteristics,其中可能包含一个叫做“heart rate measurement"的Characteristic
- Characteristic 特性。Characteristic可以理解为一个数据类型,它包括1个value和0至多个Descriptor
- Descriptor 对Characteristic的描述,例如范围、计量单位等,一个Descriptor包含一个Value
其中Service、Characteristic、Descriptor,这三部分是BLE的核心,都由UUID作为唯一标示符。一般来说,Characteristic是手机与BLE终端交换数据的关键,Characteristic有较多的跟权限相关的字段,例如PERMISSION和PROPERTY,而其中最常用的是PROPERTY。
2. BLE编程
1. 权限配置
由于android4.3及以上才支持BLE,因此需指定编译版本为targetSdkVersion大于等于18。并且需要在AndroidManifest.xml文件中配置如下所示的权限
<uses-permissionandroid:name="android.permission.BLUETOOTH"/><uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN"/>
2. 编程步骤
1.获取BluetoothManager服务及BluetoothAdapter实例
BluetoothManager是系统管理蓝牙的一种服务,获取了BluetoothManager我们就可以通过其getAdapter()获取蓝牙适配器了。
//1.获取蓝牙管理服务及BluetoothAdapter实例 mBluetoothManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = mBluetoothManager.getAdapter(); if (mBluetoothAdapter == null){ return; }
2.打开蓝牙
接下来调用BluetoothAdapter的isEnabled()判断蓝牙是否打开,未打开我们可以发送一个action为BluetoothAdapter.ACTION_REQUEST_ENABLE的intent来打开蓝牙。
//2. 判断蓝牙是否打开,没有打开就打开 if (!mBluetoothAdapter.isEnabled()){ Intent intent = newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent,REQUEST_ENABLE_BT); }
这时界面上回弹出一个对话框提示我们打开蓝牙,打开成功后会回调Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法,我们可以在里面提示一些信息。比如提示蓝牙已经打开等。
@Override protected void onActivityResult(int requestCode, int resultCode, Intentdata) { super.onActivityResult(requestCode, resultCode, data); if (resultCode != RESULT_OK){ return; } if (requestCode == REQUEST_ENABLE_BT){ Toast.makeText(this,"蓝牙已开启",Toast.LENGTH_LONG).show(); } }
3.扫描周围的BLE蓝牙设备
扫描BLE蓝牙设备,对于4.3以上的系统,直接调用startLeScan(BluetoothAdapter.LeScanCallbackcallback)即可扫描出BLE设备,在callback中会回调。但是对于5.0以上的系统,android添加了新的API,原有的startLeScan(BluetoothAdapter.LeScanCallback callback)已经被废弃,在5.0以上的系统中是使用BluetoothLeScanner的startScan(ScanCallbackcallback),回调也是ScanCallback了。
/** * 扫描Bluetooth LE * @param enable */ private void scanBleDevice(boolean enable){ //android 5.0 以前 if (Build.VERSION.SDK_INT < 21){ if (enable){ mHandler.postDelayed(new Runnable() { @Override public void run() { mScaning = false; mBluetoothAdapter.stopLeScan(mLeScanCallback); } },SCAN_SECOND); mScaning = true; mBluetoothAdapter.startLeScan(mLeScanCallback); } else { mScaning = false; mBluetoothAdapter.stopLeScan(mLeScanCallback); } } else { scanner = mBluetoothAdapter.getBluetoothLeScanner(); scanner.startScan(mScanCallback); mHandler.postDelayed(new Runnable() { @Override public void run() { scanner.stopScan(mScanCallback); } },SCAN_SECOND); } }
扫描的回调如下:
//sacn扫描回调 5.0以上用 private ScanCallback mScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { BluetoothDevice device =result.getDevice(); if (device != null){ //过滤掉其他设备 if (device.getName() != null&& device.getName().startsWith("WINPOS")){ BLEDevice bleDevice = newBLEDevice(device.getName(),device.getAddress()); if(!mBLEDeviceList.contains(bleDevice)){ mBLEDeviceList.add(bleDevice); showBluetoothLeDevice(bleDevice); } } } } @Override public void onBatchScanResults(List<ScanResult> results) { Log.d(TAG,"onBatchScanResults"); } @Override public void onScanFailed(int errorCode) { Log.d(TAG,"onScanFailed"); } }; //4.3以上 private BluetoothAdapter.LeScanCallback mLeScanCallback = newBluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice bluetoothDevice, int i,byte[] bytes) { if (bluetoothDevice != null){ //过滤掉其他设备 if (bluetoothDevice.getName()!= null && bluetoothDevice.getName().startsWith("WINPOS")){ BLEDevice bleDevice = newBLEDevice(bluetoothDevice.getName(),bluetoothDevice.getAddress()); if(!mBLEDeviceList.contains(bleDevice)){ mBLEDeviceList.add(bleDevice); showBluetoothLeDevice(bleDevice); } } } } };
这里我预先定义了BLEDevice类,用来表示BLE设备。定义如下:
public class BLEDevice { private String name; private String mac; public BLEDevice(String name, String mac) { this.name = name; this.mac = mac; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMac() { return mac; } public void setMac(String mac) { this.mac = mac; } @Override public boolean equals(Object o) { return !TextUtils.isEmpty(this.mac) &&!TextUtils.isEmpty(((BLEDevice)o).mac) &&this.mac.equals(((BLEDevice) o).getMac()); }}
扫描时我将扫描到的设备添加到List<BLEDevice> mBLEDeviceList中并显示出来。
/** * 显示BLE设备 * @param device */ private void showBluetoothLeDevice(BLEDevice device){ if (device == null){ showToast("没有发现BLE设备"); return; } mTextView.append(device.getName() + " " + device.getMac() + "\n"); }
4.获取远程设备,连接GATT服务
- android BLE 编程详解
- Android BLE编程实现
- Android之BLE编程
- Android BLE编程指南
- Android BLE编程
- 浅谈Android BLE编程
- android 蓝牙Ble详解
- BLE简介和Android BLE编程
- BLE简介和Android BLE编程
- BLE简介和Android BLE编程
- BLE简介和Android BLE编程
- BLE简介和Android BLE编程
- BLE简介和Android BLE编程
- Android 蓝牙BLE开发详解
- Android蓝牙BLE开发详解
- Android下的BLE编程解析(一)
- Android下的BLE编程解析(二)
- Android BLE蓝牙4.0开发详解
- 通过URL传参和通过json传参后台实例
- Rails poj 1363
- Hibernate学习笔记----二级缓存
- 正确单例的创建方法--Singleton设计模式
- eclipse打开JS JSP卡死 反应慢 解决方法
- android BLE 编程详解
- Android中pullToRefresh使用
- Android中viewPager的一两点使用
- android 中listview之BaseAdapter的使用
- Android 数据传递(一) Activity之间的数据传递
- Android 数据传递(二)Activity与fragment之间的通信
- Android Activity的生命周期简单总结
- 构建高并发高可用的电商平台架构实践
- Android消息机制