android BLE

android4.3 nei内置了ble并为上层app提供相应的接口来使用BLE功能。


BLE主要涉及的协议及术语:


GenericAttribute Profile (GATT)

BLE上层的协议都是基于GATT,它是一个通用的规范,通过BLE连接发送/接收属性值。


bluetoothSIG定义了很多的ble协议。


AttributeProtocol (ATT)

GATT是建立在ATT之上。也被称为GATT/ATT


ATT运行在ble设备上,所以被优化,尽可能的占用较少的字节。


每一个属性被指定一个UUID,通过ATT传输的属性被格式化位特性(characteristics)或服务(services)。


Characteristic

一个特性包含一个单一的值和0-n个描述符(Descriptor)来描述这个特性值。一个特性可以被看作一个类型。


Descriptor

描述符被定义为属性,这些属性用来描述特性的值。

例如:规定特性值的取值范围,特性值的单位等


Service

服务是一组特性的集合。例如:“心率检测”服务包含“心速测量”的特性。


角色和职责

中心与外围:被应用于BLE连接本身,中心角色设备扫描/寻找广播,外围设备角色发出广播。


GATTserver vs. GATT client

这个决定了两个设备在建立连接之后如何交互。


android手机和BLE设备的区别:手机支持中心角色(centralrole),BLE设备支持peripheralrole


一旦建立连接,他们就开始相互传输gatt数据,根据传输的数据的种类其中的一个可能作为服务器。

如果BLE设备想报告数据给手机,它可能让BLE设备的传感器作为服务器。如果BLE设备准备接收来自手机的数据,手机的传感器就作为服务端。


以上例子说明:androidapp GATT clientGATTclient GATT server 获取数据。也可以设计android app 作为GATTserver


BLE权限:

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



如果想把app提供给不支持BLE的设备需要设置android:required="fasle",然后在运行时进行判断:

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



设置BLE


1:获取BluetoothAdapter


BluetoothAdapter是所有蓝牙功能所必需的,整个系统只有一个BluetoothAdapter,获取BluetoothAdapter之后就可以进行各种蓝牙的操作了。

// Initializes Bluetooth adapter.
final BluetoothManager bluetoothManager =
        (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();


2:启动蓝牙

通过isEnabled()判断是否启动,如果没有启动,通过下面的方式启动:

private BluetoothAdapter mBluetoothAdapter;
...
// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}


3:查找BLE设备

通过startLeScan查找LE设备,并实现LeScanCallback作为参数。

注意事项:1:一旦找到所查找的设备,立即停止扫描

2:设置扫描超时,避免循环扫描。


public class DeviceScanActivity extends ListActivity {
    private BluetoothAdapter mBluetoothAdapter;
    private boolean mScanning;
    private Handler mHandler;
    // Stops scanning after 10 seconds.
    private static final long SCAN_PERIOD = 10000;
    ...
    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);
        }
        ...
    }
...
}



如果需要查找特定类型的LE设备,需要使用startLeScan(UUID[],BluetoothAdapter.LeScanCallback()),提供一个你的设备支持的服务的UUID数组。


LeScanCallback的实现:


private LeDeviceListAdapter mLeDeviceListAdapter;
...
// Device scan callback.
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();
           }
       });
   }
};


注意:要么搜索经典蓝牙,要么搜索BLE,两者不能同时搜索。


连接GATTserver

使用connectGatt连接到BLE设备的GATT server,

mBluetoothGatt = device.connectGatt(this, false, mGattCallback);



将会返回一个BluetoothGatt实例,通过这个实例可以进行Gattclient的各种操作。调用者(androidapp)是GattclientGattCallback用来提供结果给客户端。


读取BLE的属性

如果androidapp已经连接了Gatt server并且发现了服务,就能够进行属性的读写了。



收取Gatt的通知


通常BLEapp需要被通知,如果BLE设备的特性发生了改变。

使用setCharacteristicNotification方法为一个特性设置通知:

private BluetoothGatt mBluetoothGatt;
BluetoothGattCharacteristic characteristic;
boolean enabled;
...
mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
...
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
        UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);


一旦一个特性被设置为通知可用,远端设备的特性发生改变就会触发onCharacteristicChanged

回调。

@Override
// Characteristic notification
public void onCharacteristicChanged(BluetoothGatt gatt,
        BluetoothGattCharacteristic characteristic) {
    broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}


关闭clientapp

结束和BLE设备的通讯后,需要释放资源:

public void close() {
    if (mBluetoothGatt == null) {
        return;
    }
    mBluetoothGatt.close();
    mBluetoothGatt = null;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值