android - 将 BLE 设备连接到 Android 并发送数据 (nUART)

标签 android bluetooth-lowenergy

我正在尝试将 BLE 设备 (Adafruit Feather M0 Bluefruit LE) 连接到 Android 应用程序。 Feather 有一个传感器,可在特殊传感器事件上发送 UART 文本。

我想要

  • 连接到设备(静态 MAC 地址)
  • 连接到 Nordic-UART 服务
  • 接收来自羽毛的短信
  • 实现连接监控

现在我正在尝试了解 BLE 的工作原理。我了解如何连接到设备,但在那之后我就不再了解它了。

  1. 如何连接到该服务或者它是否自动连接到该服务?
  2. 我需要什么才能获取传入数据的数据或通知?

这是现在的代码。现在有检查,所以当事情没有按计划发生时它就会崩溃。但我正在尝试了解 BLE 的事情。而且它不是服务,只是 Activity 。我无法测试它,因为智能手机不会早于本周末交付。

package de.example.bluetoothletest;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {

private BluetoothAdapter mBluetoothAdapter;
private BluetoothGatt mBluetoothGatt;
private String deviceaddress=("FC:57:1A:B7:22:AD");
public final static String ACTION_DATA_AVAILABLE = "de.example.BluetoothLETest.ACTION_DATA_AVAILABLE";
public static final UUID RX_SERVICE_UUID = UUID.fromString("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
public static final UUID RX_CHAR_UUID = UUID.fromString("6e400002-b5a3-f393-e0a9-e50e24dcca9e");
public static final UUID TX_CHAR_UUID = UUID.fromString("6e400003-b5a3-f393-e0a9-e50e24dcca9e");
public static String EXTRA_DATA="de.example.BluetoothLETest.EXTRA_DATA";


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);



    //get the BluetoothAdapter
    final BluetoothManager mbluetoothManager=(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    mBluetoothAdapter=mbluetoothManager.getAdapter();

}
public void connect(){
    //connect to the given deviceaddress
    BluetoothDevice device=mBluetoothAdapter.getRemoteDevice(deviceaddress);
    mBluetoothGatt=device.connectGatt(this, false, mGattCallback);
    //now we get callbacks on mGattCallback
}

//get callbacks when something changes
private final BluetoothGattCallback mGattCallback=new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        if (newState== BluetoothProfile.STATE_CONNECTED){
            //device connected
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        if (status==BluetoothGatt.GATT_SUCCESS){
            //all Services have been discovered
        }
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        //we are still connected to the service
        if (status==BluetoothGatt.GATT_SUCCESS){
            //send the characteristic to broadcastupdate
            broadcastupdate(ACTION_DATA_AVAILABLE, characteristic);
        }
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        //send the characteristic to broadcastupdate
        broadcastupdate(ACTION_DATA_AVAILABLE, characteristic);
    }
};

//Get the 'real' data out of characteristic
private void broadcastupdate(final String action,final BluetoothGattCharacteristic characteristic){
    final Intent intent= new Intent(action);
    //only  when it is the right characteristic?/service?
    if (TX_CHAR_UUID.equals(characteristic.getUuid())){
        //get the 'real' data from the stream
        intent.putExtra(EXTRA_DATA, characteristic.getValue());
        //send the extracted data via LocalBroadcastManager
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

    }

}
}

此代码是否有效以及智能手机接收到的内容?如何连接到特定服务,还是因为设备仅提供一项服务而自动完成?

最佳答案

将您的连接方法更改为:

if (newState == BluetoothProfile.STATE_CONNECTED) {
                    intentAction = ACTION_GATT_CONNECTED;
                    broadcastUpdate(intentAction);
                    gatt.discoverServices();
                }

并在 serviceDiscoverd 上

@Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            List<BluetoothGattService> services = gatt.getServices();
            gatt.readCharacteristic(services.get(1).getCharacteristics().get(0));
            String uuid;
            List<BluetoothGattCharacteristic> gattCharacteristics;
            ArrayList<BluetoothGattCharacteristic> charas;
            for (BluetoothGattService gattService : services) {
                gattCharacteristics =
                        gattService.getCharacteristics();
                charas = new ArrayList<>();
                for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                    charas.add(gattCharacteristic);
                    uuid = gattCharacteristic.getUuid().toString();
                    if (uuid.equals("0000fff4-0000-1000-8000-00805f9b34fb")) {
                        final int charaProp = gattCharacteristic.getProperties();
                        if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                            BluetoothGattCharacteristic mNotifyCharacteristic = gattCharacteristic;
                            setCharacteristicNotification(
                                    gattCharacteristic, true);
                        }
                    }
                }
            }
        }

public void setCharacteristicNotification(final BluetoothGattCharacteristic characteristic,
                                              boolean enabled) {
        if (mBluetoothAdapter == null || mGatt == null) {
            return;
        }
        mGatt.setCharacteristicNotification(characteristic, enabled);

        Log.e("uuid service", characteristic.getUuid() + "");
        String uuid = "0000fff2-0000-1000-8000-00805f9b34fb";

        if (uuid.equals(characteristic.getUuid().toString())) {
            Log.e("uuid service2", characteristic.getUuid() + "");
            BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
                    UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
            if (descriptor != null) {
                descriptor.setValue(enabled ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : new byte[]{0x00, 0x00});
                mGatt.writeDescriptor(descriptor);
            }
        }
    }

现在你终于读到了卡片的特征:

@Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);
            updateStatus(characteristic);
            Log.e("gatt", "readChar");
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);
            updateStatus(characteristic);
            Log.e("gatt", "writeChar");
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            updateStatus(characteristic);
            Log.e("gatt", "changeChar");
        }

关于android - 将 BLE 设备连接到 Android 并发送数据 (nUART),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41801626/

相关文章:

android - SQLite 数据库 - 只创建了一个表

java - FFmpeg - 找不到 ExecuteBinaryResponseHandler - Android/Java

经典和 BTLE 设备的 Android 蓝牙扫描

linux - 以非 root 用户身份访问 Bluez 库

iOS 仅将一项服务宣传为外设 BTLE

swift - 通过 ios 应用程序快速将数据写入蓝牙设备

java - 在布局中使用表面 View 隐藏/显示软键盘时的黑色区域

java - REST GET 响应包含 HashMap 的对象

java - 如何用数字和章程组合的 5 位数字创建随机数

xcode - CoreBluetooth 框架和 IOBluetooth 框架的区别