• 安卓低功耗蓝牙——手机作为外围设备


    概述

    自安卓5.0后,谷歌加入了对安卓手机作为低功耗蓝牙外围设备,即服务端的支持。使得手机可以通过低功耗蓝牙进行相互通信。

    开发步骤

    实现这一功能其实只需要分为设置广播和设置服务器两个部分完成即可

    设置服务器

    这一步骤主要操作的是BluetoothGattServer。 
    这里写图片描述
    1. 定义一个BluetoothGattServerCallback的回调如下

    private BluetoothGattServerCallback bluetoothGattServerCallback = new BluetoothGattServerCallback() {
            @Override
            public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
                Log.v("onConnectionStateChange","连接状态改变");
            }
    
            @Override
            public void onServiceAdded(int status, BluetoothGattService service) {
                Log.v("onServiceAdded","成功添加服务");
            }
    
            @Override
            public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
                Log.v("CharacteristicReadReq","远程设备请求读取数据");
                bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, new byte[]{1,2,3,4,5,6,7,8,9,0});
            }
    
            @Override
            public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
                Log.v("CharacteristicWriteReq","远程设备请求写入数据");
                bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, new byte[]{0,9,8,7,6,5,4,3,2,1});
    
            @Override
            public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
                Log.v("DescriptorReadReq","远程设备请求写入描述器");
                bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, new byte[]{10,11,12,13,14,15,16,17,18,19});
            }
    
            @Override
            public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
                Log.v("DescriptorReadReq","远程设备请求写入描述器");
                bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, new byte[]{19,18,17,16,15,14,13,12,11,10});
            }
    
            @Override
            public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
                Log.v("onExecuteWrite","执行挂起写入操作");
            }
    
            @Override
            public void onNotificationSent(BluetoothDevice device, int status) {
                Log.v("onNotificationSent","通知发送");
            }
    
            @Override
            public void onMtuChanged(BluetoothDevice device, int mtu) {
                Log.v("onMtuChanged","mtu改变");
            }
        };
    1. 利用BluetoothManager的openGattServer(Context,BluetoothServerCallback)方法获得BluetoothGattServer实例。
    BluetoothManager mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    bluetoothGattServer = mBluetoothManager.openGattServer(this, bluetoothGattServerCallback);

    3.为设备添加相应的service,characteristic和descriptor(非必须,但通常都会用到)。这里仅举一个例子。

    BluetoothGattCharacteristic characteristic= new BluetoothGattCharacteristic(CHARACTERISTIC_UUID,por,per);
            BluetoothGattService service= new BluetoothGattService(SERVICE_UUID,pri);
            service.addCharacteristic(characteristic);
            bluetoothGattServer.addService(service);

    其中,por,per,pri分别为:

    private int por = BluetoothGattCharacteristic.PROPERTY_NOTIFY | BluetoothGattCharacteristic.PROPERTY_INDICATE | BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE;
        private int per = BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE;
        private int pri = BluetoothGattService.SERVICE_TYPE_PRIMARY;

    可根据自己的需要进行调整。 
    这样就完成了对BluetoothGattServer的简单设置。

    设置广播

    这里主要操作BluetoothLeAdvertiser。 
    这里写图片描述
    1. 利用BluetoothManager获取BluetoothAdapter,然后再通过BluetoothAdapter的getBluetoothLeAdvertiser()方法获取BluetoothLeAdvertiser的实例。

    BluetoothManager mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
            mBluetoothAdapter = mBluetoothManager.getAdapter();
            mBluetoothLeAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
    1. 开启广播 
      这里写图片描述
      这里需要准备三个东西,AdvertiseSettings,AdvertiseData和AdvertiseCallback。 
      • AdvertiseSettings 
        广播的配置实例,通过AdvertiseSettings.Builder获得。 
        这里写图片描述
        AdvertiseSettings.Builder具有四个设置参数的方法。 
        分别是
    setAdvertiseMode(int advertiseMode)设置广播的模式,低功耗,平衡和低延迟三种模式;
    setConnectable(boolean connectable)设置是否可以连接。
    setTimeout(int timeoutMillis)设置广播的最长时间
    setTxPowerLevel(int txPowerLevel)设置广播的信号强度

    可根据需要自行设定,若不设定则按照默认的参数设定。 
    这里只提供一个小例子。

    AdvertiseSettings settings = new AdvertiseSettings.Builder()
                    .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
                    .setTimeout(0)
                    .setConnectable(true)
                    .build();
    • AdvertiseData 
      广播内容的实例,通过AdvertiseData.Builder获得 
      这里写图片描述
      内含几个成员函数。
    addManufacturerData(int manufacturerId, byte[] manufacturerSpecificData)添加厂商信息,貌似不怎么用到。
    addServiceUuid(ParcelUuid serviceUuid),addServiceData(ParcelUuid serviceDataUuid, byte[] serviceData)添加服务进广播,即对外广播本设备拥有的服务。
    setIncludeDeviceName(boolean includeDeviceName)是否广播设备名称。
    setIncludeTxPowerLevel(boolean includeTxPowerLevel)是否广播信号强度

    这里提供一个简单的例子。

    AdvertiseData advertiseData = new AdvertiseData.Builder()
                    .setIncludeDeviceName(true)
                    .setIncludeTxPowerLevel(true)
                    .addServiceUuid(new ParcelUuid(SERVICE_UUID))
                    .build();
    • AdvertiseCallback 
      广播成功或者失败的回调,比较简单。
    private AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() {
            @Override
            public void onStartSuccess(AdvertiseSettings settingsInEffect) {
                Log.v("start","广播成功");
            }
    
            @Override
            public void onStartFailure(int errorCode) {
                Log.v("广播失败",String.valueOf(errorCode));
            }
        };

    最后通过BluetoothLeAdvertise的startAdvertising(AdvertiseSettings settings, AdvertiseData advertiseData, AdvertiseCallback callback)开启广播即可 
    3. 关闭广播 
    通过BluetoothLeAdvertise的stopAdvertising(AdvertiseCallback callback)关闭。

    参考链接:https://developer.android.google.cn/reference/android/bluetooth/le/BluetoothLeAdvertiser.html 
    代码资源:http://download.csdn.net/detail/will4906/9777135

  • 相关阅读:
    matlab函数集锦
    视觉(1)[导入]EStereo
    我为啥申请这里的博客?
    [导入]给定一个英文原文,统计文件里面一共有多少个不同的英文单词
    视觉(2)[导入]opengl贴图程序
    C++ Builder 控件的卸载<转载>
    [转]<不知道能否解决先转下来再说>不显示删除回复显示所有回复显示星级回复显示得分回复 没有找到MSVR90D.dll因此这个应用程序未能启动
    终于把《windows程序设计》上册读完了,hoho
    乱思。。。。。。。、、、、、
    测试windows live writer
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/9314572.html
Copyright © 2020-2023  润新知