Android Using BluetoothGattServer

2019-04-17 08:28发布

For an application I have need for an android device to be both a Ble Gatt peripheral and server to accept both incoming and send outgoing messages; however, it seems I cannot find much information pertaining to setting up and maintaining the server other than looking at projects of others in github. Can anyone show me the correct solution or guide me to more information regarding setting up BluetoothGattServer.

1条回答
Animai°情兽
2楼-- · 2019-04-17 08:55

I would like to quickly mention, that most of the Android devices in use don't support the BluetoothGattServer. However newer models have that capability more and more.

First of all you probably want to advertise your service, so that other devices know about the server. For that we need to create the AdvertiseSettings, the AdvertiseData and the AdvertiseData for ScanResponses.

AdvertiseSettings settings = new AdvertiseSettings.Builder()
                .setConnectable(true)
                .build();

AdvertiseData advertiseData = new AdvertiseData.Builder()
                    .setIncludeDeviceName(true)
                    .setIncludeTxPowerLevel(true)
                    .build();

AdvertiseData scanResponseData = new AdvertiseData.Builder()
                    .addServiceUuid(new ParcelUuid(your_service_uuid))
                    .setIncludeTxPowerLevel(true)
                    .build();

After that you need to create a callback for the advertising status:

AdvertiseCallback callback = new AdvertiseCallback() {
                @Override
                public void onStartSuccess(AdvertiseSettings settingsInEffect) {
                    Log.d(TAG, "BLE advertisement added successfully");
                }

                @Override
                public void onStartFailure(int errorCode) {
                    Log.e(TAG, "Failed to add BLE advertisement, reason: " + errorCode);
                }
            };

Now you can start advertising your service:

BluetoothLeAdvertiser bluetoothLeAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
bluetoothLeAdvertiser.startAdvertising(settings, advertiseData, scanResponseData, callback);

For the BluetoothGattServer we need first to create a BluetoothGattServerCallback:

BluetoothGattServerCallback callback = new BluetoothGattServerCallback() {
            @Override
            public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
                super.onConnectionStateChange(device, status, newState);
            }

            @Override
            public void onServiceAdded(int status, BluetoothGattService service) {
                super.onServiceAdded(status, service);
            }

            @Override
            public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
                super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
            }

            @Override
            public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
                super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);
            }

            @Override
            public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
                super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite, responseNeeded, offset, value);
            }

            @Override
            public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
                super.onDescriptorReadRequest(device, requestId, offset, descriptor);
            }

            @Override
            public void onNotificationSent(BluetoothDevice device, int status) {
                super.onNotificationSent(device, status);
            }

            @Override
            public void onMtuChanged(BluetoothDevice device, int mtu) {
                super.onMtuChanged(device, mtu);
            }

            @Override
            public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
                super.onExecuteWrite(device, requestId, execute);
            }
        };

You don't need to implement all of those methods, only those you are interested in. For example you could implement the onCharacteristicReadRequest(...) method to return data to a device reading the characteristic on your BluetoothGattServer.

After that you can open a GattServer, create your service and add the service to the server:

BluetoothGattServer bluetoothGattServer = mBluetoothManager.openGattServer(Context, callback);
BluetoothGattService service = new BluetoothGattService(your_service_uuid, BluetoothGattService.SERVICE_TYPE_PRIMARY);

//add a read characteristic.
BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(your_characteristic_uuid, BluetoothGattCharacteristic.PROPERTY_READ, BluetoothGattCharacteristic.PERMISSION_READ);

service.addCharacteristic(characteristic)

bluetoothGattServer.addService(service);

Now you have setup your BluetoothGattServer with a read characteristic, from which other devices can read. I hope this short summary helps you, otherwise I will try to help you clarify the unclear things.

查看更多
登录 后发表回答