android ble蓝牙接收不到数据_Android蓝牙4.0 Ble读写数据详解 -2

Android蓝牙4.0 Ble读写数据详解 -2

上一篇说了如何扫描与链接蓝牙 这篇文章讲讲与蓝牙的数据传输,与一些踩到的坑。

先介绍一款调试工具,专门调试Ble蓝牙的app。名字叫:nRF-Connect 谷歌应用商店也能下载到。

这里我先连接一个蓝牙设备 贴几个截图。

UUID的话 就相当于钥匙,蓝牙设备当中有通道,那么通道是需要UUID进行匹配的

当连接上设备之后,可以看到UUID的通道 接下来,按照设备厂商提供的文档,找到我们需要的UUID通道

比如说我这里需要的是0x6a的Service通道 然后点开最后一个Service通道查看

展开Service后 可以看到有两个Characteristic通道

我们看Properties属性 一个是NOTIFY 一个是WRITE 也有可能会有READ这个属性的通道

可以拿这个app输出写出指令给蓝牙,在不清楚是蓝牙的问题还是自己的问题的时候,这个工具还是挺好使的。

Notify的话,需要注意这个Descriptors的UUID 这个在注册Notify的时候,需要用到,这里虽然看不全,但是之后可以通过打印得到。

简单说一下这三种属性的通道的用途

WRITE:顾名思义,写的意思,该通道是用来向蓝牙设备写出数据的通道

READ:向蓝牙设备进行读取数据的通道 这个通道有一个坑 后续会详细写上

Notify:该通道需要注册监听,这是一个通知的通道,蓝牙向你传输数据的话,就能直接收到监听。

我这边的话 因为一些原因,所以没有使用READ通道获取数据 只用了Notify通道 当然 也会讲讲怎么使用READ

准备工作

先将UUID管理起来,我这里的话 采用静态常量的形式保存起来了。

public class UUIDManager {

/**

* 服务的UUID

*/

public static final String SERVICE_UUID = "00006a00-0000-1000-8000-00805f9b34fb";

/**

* 订阅通知的UUID

*/

public static final String NOTIFY_UUID = "00006a02-0000-1000-8000-00805f9b34fb";

/**

* 写出数据的UUID

*/

public static final String WRITE_UUID = "00006a02-0000-1000-8000-00805f9b34fb";

/**

* NOTIFY里面的Descriptor UUID

*/

public static final String NOTIFY_DESCRIPTOR = "00002902-0000-1000-8000-00805f9b34fb";

}

处理通知回调接口

蓝牙的数据回调,其实并不是回调到主线程当中,所以如果接收到数据之后,就进行视图操作的话,是会失败的。

所以我打算切换到主线程进行回调,当然,也可以使用EventBus,不过我不喜欢这东西就没去用。

回调接口的话,打算使用list集合存储起来,然后回调到各个需要数据的地方。 创建以下三个类

/**

* Created by Pencilso on 2017/4/20.

* 蓝牙数据回调监听接口

*/

public interface BlueNotifyListener {

public void onNotify(Message notify);

}

/**

* Created by Pencilso on 2017/4/25.

* 处理回调所有接口

*/

public class NotifyThread implements Runnable {

private List listeners;

private Message notify;

@Override

public void run() {

if (notify == null || listeners==null)

return;

try {

Iterator iterator = listeners.iterator();

while (iterator.hasNext()) {

BlueNotifyListener next = iterator.next();

if (next == null)

iterator.remove();

else

next.onNotify(notify);

}

} catch (Exception e) {

e.printStackTrace();

}

}

public void setListeners(List listeners) {

this.listeners = listeners;

}

public void setNotify(Message notify) {

this.notify = notify;

}

}

/**

* Created by Pencilso on 2017/4/26.

* 蓝牙的Code类 用来自定义回调的标识

*/

public class BlueCodeUtils {

/**

* 蓝牙状态 已连接

*/

public static final int BLUETOOTH_STATE_CONNECT = 0x1;

/**

* 蓝牙状态 已断开

*/

public static final int BLUETOOTH_STATE_DISCONNECT

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ESP-IDF是一款用于ESP32和ESP8266的官方开发框架,其中包含了丰富的蓝牙接口。下面是一个简单的蓝牙数据发送接收例程。 发送数据: ```c #include <stdio.h> #include "esp_bt.h" #include "esp_bt_main.h" #include "esp_gap_ble_api.h" #define GATTS_TAG "GATTS_DEMO" //定义GATT服务UUID #define GATTS_SERVICE_UUID_TEST_A 0x00FF //定义GATT特征UUID #define GATTS_CHAR_UUID_TEST_A 0xFF01 static uint8_t adv_config_done = 0; //GATT服务定义 static uint8_t test_service_uuid[16] = { /* LSB <--------------------------------------------------------------------------------> MSB */ //first uuid, 16bit, [12],[13] is the value 0x1b,0x9a, //second uuid, 16bit, [12],[13] is the value 0x12,0x34, //third uuid, 32bit, [12],[13],[14],[15] is the value, 0x0000XXXX is a placeholder 0x11,0x22,0x33,0x44, 0x00,0x00,0x00,0x00, }; //GATT特征定义 static uint8_t test_char_uuid[16] = { /* LSB <--------------------------------------------------------------------------------> MSB */ //first uuid, 16bit, [12],[13] is the value 0x1b,0x9a, //second uuid, 16bit, [12],[13] is the value 0x12,0x34, //third uuid, 32bit, [12],[13],[14],[15] is the value, 0x0000XXXX is a placeholder 0x11,0x22,0x33,0x44, 0x00,0x00,0x00,0x00, }; //GATT特征值 static uint8_t test_char_value[20] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; //GATT事件处理函数 static esp_gatts_cb_event_t gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { switch (event) { case ESP_GATTS_REG_EVT: //注册GATT事件 esp_ble_gap_set_device_name("ESP_GATTS_DEMO"); esp_ble_gatts_create_attr_tab((esp_gatts_attr_db_t *)param->create.db, gatts_if, param->create.svc_inst_id, param->create.num_handle); break; case ESP_GATTS_CREAT_ATTR_TAB_EVT: if (param->add_attr_tab.status != ESP_GATT_OK) { printf("create attribute table failed, error code=0x%x\n", param->add_attr_tab.status); } else if (param->add_attr_tab.num_handle != ESP_GATT_AUTO_RSP) { //获取特征值句柄 printf("create attribute table success, the number handle = %d\n", param->add_attr_tab.num_handle); } else { printf("create attribute table success, the number handle = %d\n", param->add_attr_tab.num_handle); } //注册服务 esp_ble_gatts_start_service(param->add_attr_tab.handles[0]); break; case ESP_GATTS_CONNECT_EVT: printf("a remote device connected\n"); break; case ESP_GATTS_DISCONNECT_EVT: printf("a remote device disconnected\n"); break; case ESP_GATTS_WRITE_EVT: if (param->write.handle == test_handle_table[IDX_CHAR_VAL_A]) { memcpy(test_char_value, param->write.value, param->write.len); printf("write test_char_value=%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n", test_char_value[0],test_char_value[1],test_char_value[2],test_char_value[3], test_char_value[4],test_char_value[5],test_char_value[6],test_char_value[7], test_char_value[8],test_char_value[9]); } //确认写入数据 esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); break; case ESP_GATTS_EXEC_WRITE_EVT: esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); break; default: break; } return ESP_GATT_OK; } void gatt_server_init(void) { //GATT参数初始化 esp_err_t ret; esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); ret = esp_bt_controller_init(&bt_cfg); if (ret) { printf("%s initialize controller failed\n", __func__); return; } ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); if (ret) { printf("%s enable controller failed\n", __func__); return; } ret = esp_bluedroid_init(); if (ret) { printf("%s init bluetooth failed\n", __func__); return; } ret = esp_bluedroid_enable(); if (ret) { printf("%s enable bluetooth failed\n", __func__); return; } //GATT事件注册 esp_ble_gatts_register_callback(gatts_event_handler); esp_ble_gatts_app_register(GATTS_APP_ID); //创建服务表 esp_ble_gatts_create_service(GATTS_IF_NUM, test_service_uuid, GATTS_NUM_HANDLE_TEST_A); } void app_main() { gatt_server_init(); //循环发送数据 while (1) { esp_ble_gatts_set_attr_value(test_handle_table[IDX_CHAR_VAL_A], sizeof(test_char_value), test_char_value); vTaskDelay(1000 / portTICK_PERIOD_MS); } } ``` 接收数据: ```c #include <stdio.h> #include "esp_bt.h" #include "esp_bt_main.h" #include "esp_gap_ble_api.h" #define GATTC_TAG "GATTC_DEMO" static uint8_t remote_bda[ESP_BD_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; static esp_gattc_char_elem_t *char_elem_result = NULL; static esp_gattc_descr_elem_t *descr_elem_result = NULL; static uint16_t char_handle = 0; static uint16_t descr_handle = 0; //GATT事件处理函数 static void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) { switch (event) { case ESP_GATTC_REG_EVT: //注册GATT事件 esp_ble_gap_set_scan_params(&ble_scan_params); break; case ESP_GATTC_CONNECT_EVT: printf("a GATT client connected\n"); esp_ble_gattc_search_service(gattc_if, param->connect.conn_id, NULL); break; case ESP_GATTC_SEARCH_RES_EVT: //搜索到服务 printf("search service uuid: "); esp_log_buffer_hex(GATTC_TAG, param->search_res.srvc_id.uuid.uuid, param->search_res.srvc_id.uuid.len); printf("search service start handle %d end handle %d\n", param->search_res.start_handle, param->search_res.end_handle); //搜索特征 esp_ble_gattc_get_char_by_uuid(gattc_if, param->search_res.conn_id, &param->search_res.srvc_id, &char_uuid, char_elem_result, &count, 0); break; case ESP_GATTC_SEARCH_CMPL_EVT: //搜索完成 printf("search complete\n"); break; case ESP_GATTC_GET_CHAR_EVT: //获取特征 printf("get char %s, handle %d\n", char_elem_result->uuid.uuid.uuid16, char_elem_result->char_handle); char_handle = char_elem_result->char_handle; //获取特征描述符 esp_ble_gattc_get_descr_by_char_handle(gattc_if, param->search_res.conn_id, char_handle, &descr_uuid, descr_elem_result, &count, 0); break; case ESP_GATTC_GET_DESCR_EVT: //获取特征描述符 printf("get descr %s, handle %d\n", descr_elem_result->uuid.uuid.uuid16, descr_elem_result->descr_handle); descr_handle = descr_elem_result->descr_handle; //开启特征通知 esp_ble_gattc_register_for_notify(gattc_if, remote_bda, char_handle); break; case ESP_GATTC_REG_FOR_NOTIFY_EVT: //注册通知事件 printf("register for notify\n"); break; case ESP_GATTC_NOTIFY_EVT: //接收到通知 printf("receive notify value:"); esp_log_buffer_hex(GATTC_TAG, param->notify.value, param->notify.value_len); break; default: break; } } void gatt_client_init(void) { //GATT参数初始化 esp_err_t ret; esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); ret = esp_bt_controller_init(&bt_cfg); if (ret) { printf("%s initialize controller failed\n", __func__); return; } ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); if (ret) { printf("%s enable controller failed\n", __func__); return; } ret = esp_bluedroid_init(); if (ret) { printf("%s init bluetooth failed\n", __func__); return; } ret = esp_bluedroid_enable(); if (ret) { printf("%s enable bluetooth failed\n", __func__); return; } //GATT事件注册 esp_ble_gattc_register_callback(gattc_event_handler); esp_ble_gattc_app_register(0); //开始扫描 esp_ble_gap_start_scanning(10); } void app_main() { gatt_client_init(); } ``` 以上代码仅供参考,实际使用中需要根据具体情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值