在Android中向蓝牙设备写入数据
虽然有人问过类似的问题,但有点不同。我知道如何将数据传递到连接的BLE设备,但我认为我做错了什么,需要帮助。 下面的代码包含我的类中扩展BroadcastReceiver的所有方法在Android中向蓝牙设备写入数据,android,bluetooth,bluetooth-lowenergy,Android,Bluetooth,Bluetooth Lowenergy,虽然有人问过类似的问题,但有点不同。我知道如何将数据传递到连接的BLE设备,但我认为我做错了什么,需要帮助。 下面的代码包含我的类中扩展BroadcastReceiver的所有方法 我扫描并连接到“笔地址”指定的设备 在`OnServicesDiscoveryd`方法中,我查找其`UUID`包含`abcd`的服务 然后,我循环遍历这些服务的特征,并在它们的“UUID”中查找具有特定字符串的三个特征 第三个特性是一个可写特性,在这个特性中,我试图通过调用方法`writeCharac(mGatt,w
writeCharac
方法中放置断点时,我发现status
值为false,表示写入未成功。
我是不是遗漏了什么?请帮忙
public class BackgroundReceiverFire extends BroadcastReceiver {
Context context;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothGatt mGatt;
private BluetoothLeService mBluetoothLeService;
private boolean mScanning;
private final String TAG = "READING: ";
private BluetoothDevice mDevice;
private Handler mHandler;
private static final int REQUEST_ENABLE_BT = 1;
private final String PEN_ADDRESS = "FB:23:AF:42:5C:56";
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
public void onReceive(Context context, Intent intent) {
this.context = context;
Toast.makeText(context, "Started Scanning", LENGTH_SHORT).show();
initializeBluetooth();
startScan();
}
private void initializeBluetooth() {
mHandler = new Handler();
// Use this check to determine whether BLE is supported on the device. Then you can
// selectively disable BLE-related features.
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager =
(BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// Checks if Bluetooth is supported on the device.
if (mBluetoothAdapter == null) {
Toast.makeText(this.context, "No Bluetooth", LENGTH_SHORT).show();
return;
}
}
private void startScan() {
scanLeDevice(true);
}
private void stopScan() {
scanLeDevice(false);
}
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;
//Scanning for the device
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
if (device.getAddress().matches(PEN_ADDRESS)) {
connectBluetooth(device);
Toast.makeText(context, "Device Found: " + device.getAddress(), Toast.LENGTH_LONG).show();
}
}
};
private void connectBluetooth(BluetoothDevice insulinPen) {
if (mGatt == null) {
Log.d("connectToDevice", "connecting to device: " + insulinPen.toString());
mDevice = insulinPen;
mGatt = insulinPen.connectGatt(context, true, gattCallback);
scanLeDevice(false);// will stop after first device detection
}
}
private void enableBluetooth() {
if (!mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.enable();
}
scanLeDevice(true);
}
private void disableBluetooth() {
if (mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.disable();
}
}
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
Log.i("onConnectionStateChange", "Status: " + status);
switch (newState) {
case BluetoothProfile.STATE_CONNECTED:
gatt.discoverServices();
break;
case BluetoothProfile.STATE_DISCONNECTED:
Log.e("gattCallback", "STATE_DISCONNECTED");
Log.i("gattCallback", "reconnecting...");
BluetoothDevice mDevice = gatt.getDevice();
mGatt = null;
connectBluetooth(mDevice);
break;
default:
Log.e("gattCallback", "STATE_OTHER");
break;
}
}
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
mGatt = gatt;
List<BluetoothGattService> services = mGatt.getServices();
Log.i("onServicesDiscovered", services.toString());
Iterator<BluetoothGattService> serviceIterator = services.iterator();
while(serviceIterator.hasNext()){
BluetoothGattService bleService = serviceIterator.next();
if(bleService.getUuid().toString().contains("abcd")){
//Toast.makeText(context,"Got the service",Toast.LENGTH_SHORT);
BluetoothGattCharacteristic readChar1 = bleService.getCharacteristics().get(0);
for (BluetoothGattDescriptor descriptor : readChar1.getDescriptors()) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
mGatt.writeDescriptor(descriptor);
mGatt.setCharacteristicNotification(readChar1, true);
}
//mGatt.readCharacteristic(readChar1);
BluetoothGattCharacteristic readChar2 = bleService.getCharacteristics().get(1);
for (BluetoothGattDescriptor descriptor : readChar2.getDescriptors()) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
mGatt.writeDescriptor(descriptor);
mGatt.setCharacteristicNotification(readChar2, true);
}
//mGatt.readCharacteristic(readChar2);
BluetoothGattCharacteristic writeChar1 = bleService.getCharacteristics().get(2);
for (BluetoothGattDescriptor descriptor : writeChar1.getDescriptors()) {
descriptor.setValue( BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
mGatt.writeDescriptor(descriptor);
mGatt.setCharacteristicNotification(writeChar1, true);
}
writeCharac(mGatt,writeChar1,123);
}
}
//gatt.readCharacteristic(therm_char);
}
public void writeCharac(BluetoothGatt gatt, BluetoothGattCharacteristic charac, int value ){
if (mBluetoothAdapter == null || gatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
/*
BluetoothGattCharacteristic charac = gattService
.getCharacteristic(uuid);
*/
if (charac == null) {
Log.e(TAG, "char not found!");
}
int unixTime = value;
String unixTimeString = Integer.toHexString(unixTime);
byte[] byteArray = hexStringToByteArray(unixTimeString);
charac.setValue(byteArray);
boolean status = mGatt.writeCharacteristic(charac);
if(status){
Toast.makeText(context,"Written Successfully",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"Error writing characteristic",Toast.LENGTH_SHORT).show();
}
}
public byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len/2];
for(int i = 0; i < len; i+=2){
data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
}
return data;
}
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic
characteristic, int status) {
Log.i("onCharacteristicRead", characteristic.toString());
String characteristicValue = characteristic.getValue().toString();
Log.d("CHARACTERISTIC VALUE: ", characteristicValue);
gatt.disconnect();
}
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic
characteristic) {
String value = characteristic.getValue().toString();
Log.d(TAG,value);
}
};
公共类背景ReceiverFire扩展广播接收器{
语境;
私人蓝牙适配器mBluetoothAdapter;
私人蓝牙GATT mGatt;
私人蓝牙服务mBluetoothLeService;
私有布尔扫描;
私有最终字符串TAG=“READING:”;
私人蓝牙设备;
私人经理人;
私有静态最终整数请求_ENABLE_BT=1;
专用最终字符串PEN_ADDRESS=“FB:23:AF:42:5C:56”;
//10秒后停止扫描。
专用静态最终长扫描周期=10000;
公共void onReceive(上下文、意图){
this.context=上下文;
Toast.makeText(上下文,“开始扫描”,长度较短).show();
初始化bluetooth();
startScan();
}
private void initializeBluetooth(){
mHandler=新处理程序();
//使用此检查确定设备上是否支持BLE。然后您可以
//有选择地禁用可编程逻辑相关功能。
//初始化蓝牙适配器。对于API级别18及以上,请获取对的参考
//BluetoothManager中的BluetoothAdapter。
最终BluetoothManager BluetoothManager=
(BluetoothManager)context.getSystemService(context.BLUETOOTH\u服务);
mBluetoothAdapter=bluetoothManager.getAdapter();
//检查设备上是否支持蓝牙。
if(mBluetoothAdapter==null){
Toast.makeText(this.context,“无蓝牙”,长度较短).show();
返回;
}
}
私有void startScan(){
扫描设备(真实);
}
私有void stopScan(){
扫描设备(假);
}
专用void扫描设备(最终布尔启用){
如果(启用){
//在预定义的扫描周期后停止扫描。
mHandler.postDelayed(新的Runnable(){
@凌驾
公开募捐{
mScanning=false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
},扫描周期);
mScanning=true;
//扫描设备
mBluetoothAdapter.startedscan(mLeScanCallback);
}否则{
mScanning=false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
私有BluetoothAdapter.LeScanCallback mLeScanCallback=
新的BluetoothAdapter.LeScanCallback(){
@凌驾
public void onLeScan(最终BluetoothDevice设备,int rssi,字节[]扫描记录){
if(device.getAddress()匹配(笔地址)){
连接蓝牙(设备);
Toast.makeText(上下文,“找到的设备:+Device.getAddress(),Toast.LENGTH_LONG.show();
}
}
};
专用蓝牙(蓝牙设备insulinPen){
如果(mGatt==null){
Log.d(“连接到设备”,“连接到设备:”+insulinPen.toString());
M设备=胰岛素;
mGatt=insulinPen.connectGatt(上下文,true,gattCallback);
scanLeDevice(false);//将在第一次检测到设备后停止
}
}
私有void enableBluetooth(){
如果(!mBluetoothAdapter.isEnabled()){
mBluetoothAdapter.enable();
}
扫描设备(真实);
}
私有无效禁用蓝牙(){
if(mBluetoothAdapter.isEnabled()){
mBluetoothAdapter.disable();
}
}
私有最终BluetoothGattCallback gattCallback=新BluetoothGattCallback(){
@凌驾
连接状态更改的公共无效(蓝牙gatt gatt、int状态、int新闻状态){
Log.i(“onConnectionStateChange”,“Status:+Status”);
交换机(新闻状态){
案例BluetoothProfile.STATE\u已连接:
关贸总协定。发现服务();
打破
案例BluetoothProfile.STATE\u已断开连接:
Log.e(“gattCallback”、“STATE_DISCONNECTED”);
Log.i(“gattCallback”,“重新连接…”);
BluetoothDevice mDevice=gatt.getDevice();
mGatt=null;
连接蓝牙(mDevice);
打破
违约:
Log.e(“gattCallback”、“STATE_OTHER”);
打破
}
}
发现服务上的公共无效(Bluetooth gatt,int状态){
mGatt=关贸总协定;
List services=mGatt.getServices();
Log.i(“OnServicesDiscovery”,services.toString());
迭代器serviceIterator=services.Iterator();
while(serviceIterator.hasNext()){
BluetoothGattService bleService=serviceIterator.next();
if(bleService.getUuid().toStri