ln:蓝牙设备列表ui添加 2800/target/4 2811/1 2811/head 2812/target/1
authorluozheng <1732036298@qq.com>
Thu, 27 Nov 2025 09:48:30 +0000 (17:48 +0800)
committerluozheng <1732036298@qq.com>
Thu, 27 Nov 2025 09:48:30 +0000 (17:48 +0800)
code/sdk/application/wearable/ln/nativeapp/nativeui/bluetooth/src/BluetoothModel.cpp
code/sdk/application/wearable/ln/nativeapp/nativeui/bluetooth/src/Ln_Bluetooth_apiC.cpp
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdBlueListAdapter.h [new file with mode: 0644]
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdBlueView.h
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdBlueListAdapter.cpp [new file with mode: 0644]
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdBlueView.cpp
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdPresenter.cpp
code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c

index f5071ed..b9c84f7 100644 (file)
@@ -146,7 +146,7 @@ void BluetoothModel::Init()
     BtInitCallBacksEx();\r
     BtInitGatts();\r
     BtInitSpp();\r
-    // InitBtHeadsetEvent(); // 蓝牙ct和tg适配初始化\r
+    InitBtHeadsetEvent(); // 蓝牙ct和tg适配初始化\r
     // PhoneServiceInit();\r
 \r
     /* 实验室测试需要,开机开广播 */\r
@@ -260,7 +260,7 @@ void BluetoothModel::SetUpConnedDevicesList()
         SetConnedDevicesListClear();\r
         unsigned int connedDevicesNum = 0;\r
         bool ret = gap_get_paired_devices_num(&connedDevicesNum);\r
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Setup GetPariedDevicesNum ret = %d, num = %d", ret, connedDevicesNum);\r
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Setup GetPariedDevicesNum ret = %d, num = %d", ret, connedDevicesNum);\r
 \r
         gap_paired_device_info_t *devInfo = (gap_paired_device_info_t*)malloc(sizeof(gap_paired_device_info_t) *connedDevicesNum);\r
         if (devInfo ==  nullptr) {\r
@@ -908,6 +908,10 @@ static void ACLConnectionFail(const bd_addr_t &bdAddr)
     unsigned char nameLen = BD_NAME_LEN;\r
     bool getNameRet = gap_get_device_name(&bdAddr, caseInfo.deviceName, &nameLen);\r
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "连接断开 deviceName: %s", caseInfo.deviceName);\r
+    // 设备名为空不处理\r
+    if(strcmp((const char *)caseInfo.deviceName, "") == 0){\r
+        return;\r
+    }\r
     if(strcmp((const char *)caseInfo.deviceName, BluetoothModel::GetInstance()->GetLastConnedDeviceName()) == 0){\r
         \r
         //亮屏操作\r
index 512e61f..abf0b40 100644 (file)
@@ -81,7 +81,7 @@ namespace OHOS
         }
         else
         {
-            results = gap_br_set_inquiry_paramters(DEVICE_MAJOR_CLASS_AUDIO_VIDEO, 10);
+            results = gap_br_set_inquiry_paramters(0, 20);
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "设置扫描参数 results %d", results);
             results = gap_br_start_discovery();
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "启动扫描 results %d", results);
diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdBlueListAdapter.h b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdBlueListAdapter.h
new file mode 100644 (file)
index 0000000..a312cc5
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: ThunderBird Bluetooth Device List Adapter
+ * Author:
+ * Create: 2024-01-01
+ */
+#ifndef THUNDERBIRD_BLUE_LIST_ADAPTER_H
+#define THUNDERBIRD_BLUE_LIST_ADAPTER_H
+
+#include <list>
+#include "components/abstract_adapter.h"
+#include "components/ui_view_group.h"
+#include "components/ui_label.h"
+#include "components/ui_image_view.h"
+#include "bluetooth/BluetoothModel.h"
+
+namespace OHOS {
+
+// 设备列表项类型
+enum class DeviceItemType : uint8_t {
+    SECTION_HEADER_CONNECTED = 0,  // 已连接设备分组标题
+    SECTION_HEADER_NEARBY,          // 附近设备分组标题
+    DEVICE_CONNECTED,               // 已连接设备
+    DEVICE_NEARBY                   // 附近的设备
+};
+
+// 设备列表项数据结构
+struct DeviceListItem {
+    DeviceItemType type;
+    BluetoothCaseInfo deviceInfo;
+    bool isSelected;
+};
+
+// 蓝牙设备列表项视图
+class ThunderBirdBlueDeviceItemView : public UIViewGroup {
+public:
+    ThunderBirdBlueDeviceItemView();
+    ~ThunderBirdBlueDeviceItemView() override;
+    
+    // 设置为设备项
+    void SetDeviceInfo(const BluetoothCaseInfo& info, bool isConnected);
+    // 设置为分组标题
+    void SetSectionHeader(const char* title);
+    // 设置选中状态
+    void SetSelected(bool selected);
+    // 获取设备信息
+    BluetoothCaseInfo* GetDeviceInfo(void);
+    // 检查是否是分组标题
+    bool IsSectionHeader(void) const { return isSectionHeader_; }
+
+private:
+    void SetupChildViews();
+    
+    UILabel nameLabel_;           // 设备名称标签
+    UIImageView connectedIcon_;   // 已连接图标(小圆点)
+    UIImageView borderImage_;     // 选中边框
+    BluetoothCaseInfo deviceInfo_{};
+    bool isSelected_{false};
+    bool isSectionHeader_{false};
+    bool isConnected_{false};
+};
+
+// 蓝牙设备列表适配器
+class ThunderBirdBlueListAdapter : public AbstractAdapter {
+public:
+    ThunderBirdBlueListAdapter();
+    ~ThunderBirdBlueListAdapter() override;
+    
+    UIView *GetView(UIView *inView, int16_t index) override;
+    uint16_t GetCount() override;
+    
+    // 刷新设备列表数据
+    void RefreshDeviceData();
+    
+    // 选择操作(按键控制)
+    void SelectNext();     // 选择下一个设备
+    void SelectPrevious(); // 选择上一个设备
+    int16_t GetSelectedIndex() const { return selectedIndex_; }
+    void SetSelectedIndex(int16_t index);
+    
+    // 获取当前选中的设备
+    BluetoothCaseInfo* GetSelectedDevice();
+    
+    // 获取设备总数(不含分组标题)
+    uint16_t GetDeviceCount() const;
+    
+    // 限制常量
+    static constexpr uint16_t MAX_CONNECTED_DEVICES = 1;   // 最多显示1个已连接设备
+    static constexpr uint16_t MAX_NEARBY_DEVICES = 10;     // 最多显示10个附近设备
+
+private:
+    // 构建显示列表
+    void BuildDisplayList();
+    // 检查索引是否为设备项(非分组标题)
+    bool IsDeviceItem(int16_t index) const;
+    // 找到下一个可选的设备项索引
+    int16_t FindNextSelectableIndex(int16_t currentIndex, bool forward);
+    
+    std::list<DeviceListItem> displayList_;  // 显示列表(包含分组标题和设备)
+    int16_t selectedIndex_{-1};               // 当前选中的索引
+    ThunderBirdBlueDeviceItemView* itemView_{nullptr};
+};
+
+} // namespace OHOS
+
+#endif // THUNDERBIRD_BLUE_LIST_ADAPTER_H
+
index 306ead8..7d7ae2e 100644 (file)
@@ -11,6 +11,9 @@
 
 namespace OHOS
 {
+    // 前向声明
+    class ThunderBirdBlueListAdapter;
+
     class ThunderBirdBlueView
     {
     public:
@@ -25,6 +28,15 @@ namespace OHOS
         void RefreshDeviceList(void);
         void HandleBluetoothViewOperation(int16_t view);
         void ExecuteDisconnect(void);
+        
+        // 按键操作接口(设备列表页面使用)
+        void OnKeyUp(void);      // 音量+键:选择上一个设备
+        void OnKeyDown(void);    // 音量-键:选择下一个设备
+        void OnKeyConfirm(void); // 确认键:连接选中的设备
+        
+        // 获取当前选中的设备索引
+        int16_t GetSelectedDeviceIndex(void) const;
+        
         enum : int16_t {
             THUNDERBIRD_BULEVIEW_ENTER = 0,          // 配对准备中页面
             THUNDERBIRD_BULEVIEW_SREACHING,          // 寻找设备
@@ -38,6 +50,9 @@ namespace OHOS
         };
 
     private:
+        void InitDeviceListAdapter(void);  // 初始化设备列表适配器
+        void UpdateDeviceListSelection(void); // 更新设备列表选中状态
+        
         UIViewGroup *group{nullptr};
         UILabelExt *TextLabel{nullptr};
         UILabelExt *TextLabel_2{nullptr};
@@ -50,8 +65,13 @@ namespace OHOS
         UIImageView *RemindIcon2{nullptr};
         UIImageView *RemindIcon3{nullptr};
         UIList *DeviceList{nullptr};
+        
+        // 设备列表适配器
+        ThunderBirdBlueListAdapter *deviceListAdapter_{nullptr};
+        
+        // 当前视图状态
+        int16_t currentShowView_{-1};
     };
 }
 
 #endif
-
diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdBlueListAdapter.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdBlueListAdapter.cpp
new file mode 100644 (file)
index 0000000..69cab2d
--- /dev/null
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: ThunderBird Bluetooth Device List Adapter
+ * Author:
+ * Create: 2024-01-01
+ */
+#include "thunderbird/include/ThunderBirdBlueListAdapter.h"
+#include "wearable_log.h"
+#include "bts_br_gap.h"
+
+namespace OHOS {
+
+// 列表项尺寸常量
+constexpr uint16_t ITEM_WIDTH = 240;
+constexpr uint16_t ITEM_HEIGHT = 40;
+constexpr uint16_t SECTION_HEADER_HEIGHT = 24;
+constexpr uint16_t ITEM_BORDER_WIDTH = 2;
+constexpr uint16_t CONNECTED_ICON_SIZE = 8;
+constexpr uint16_t LABEL_FONT_SIZE = 18;
+constexpr uint16_t SECTION_FONT_SIZE = 14;
+
+// 颜色定义
+constexpr int64_t COLOR_ITEM_BG = 0xFF4D4D4D;          // 设备项背景色(深灰)
+constexpr int64_t COLOR_BORDER_SELECTED = 0xFFED6C00;  // 选中边框颜色(橙色)
+constexpr int64_t COLOR_TEXT_WHITE = 0xFFFFFFFF;       // 白色文字
+constexpr int64_t COLOR_TEXT_GRAY = 0xFFCCCCCC;        // 灰色文字(分组标题)
+constexpr int64_t COLOR_CONNECTED_DOT = 0xFFED6C00;    // 已连接指示点颜色(橙色)
+
+//========================================
+// ThunderBirdBlueDeviceItemView 实现
+//========================================
+
+ThunderBirdBlueDeviceItemView::ThunderBirdBlueDeviceItemView()
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdBlueDeviceItemView create");
+    SetPosition(0, 0, ITEM_WIDTH, ITEM_HEIGHT);
+    SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);  // 透明背景
+    SetupChildViews();
+}
+
+ThunderBirdBlueDeviceItemView::~ThunderBirdBlueDeviceItemView()
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdBlueDeviceItemView destroy");
+    Remove(&borderImage_);
+    Remove(&nameLabel_);
+    Remove(&connectedIcon_);
+}
+
+void ThunderBirdBlueDeviceItemView::SetupChildViews()
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetupChildViews");
+
+    borderImage_.SetPosition(0, 0, ITEM_WIDTH, ITEM_HEIGHT);
+    borderImage_.SetStyle(STYLE_BACKGROUND_COLOR, COLOR_TEXT_GRAY);
+    borderImage_.SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE);
+    borderImage_.SetStyle(STYLE_BORDER_RADIUS, 10);
+    borderImage_.SetVisible(false);
+    Add(&borderImage_);
+
+    nameLabel_.SetPosition(20, 0, 200, ITEM_HEIGHT);
+    nameLabel_.SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT,UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER);
+    nameLabel_.SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS);
+    Add(&nameLabel_);
+
+    // 已连接指示图标(小圆点,右侧)
+    connectedIcon_.SetPosition(ITEM_WIDTH - 16, (ITEM_HEIGHT - CONNECTED_ICON_SIZE) / 2);
+    connectedIcon_.Resize(CONNECTED_ICON_SIZE, CONNECTED_ICON_SIZE);
+    connectedIcon_.SetStyle(STYLE_BACKGROUND_COLOR, COLOR_CONNECTED_DOT);
+    connectedIcon_.SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE);
+    connectedIcon_.SetStyle(STYLE_BORDER_RADIUS, CONNECTED_ICON_SIZE / 2);
+    connectedIcon_.SetVisible(false);
+    Add(&connectedIcon_);
+}
+
+// 设置设备信息(包括分组标题)
+void ThunderBirdBlueDeviceItemView::SetDeviceInfo(const BluetoothCaseInfo& info, bool isConnected)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetDeviceInfo name=%s isConnected=%d", 
+                  info.deviceName, isConnected);
+    
+    isSectionHeader_ = false;
+    isConnected_ = isConnected;
+    (void)memcpy_s(&deviceInfo_, sizeof(BluetoothCaseInfo), &info, sizeof(BluetoothCaseInfo));
+    
+    // 设置设备名称
+    nameLabel_.SetText(reinterpret_cast<const char*>(info.deviceName));
+    nameLabel_.SetFont(DEFAULT_VECTOR_FONT_FILENAME, LABEL_FONT_SIZE);
+    nameLabel_.SetPosition(20, 0, 200, ITEM_HEIGHT);
+    nameLabel_.SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT,UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER);
+
+    
+    // 显示/隐藏已连接指示
+    connectedIcon_.SetVisible(isConnected);
+    
+    Invalidate();
+}
+
+// 设置分组标题
+void ThunderBirdBlueDeviceItemView::SetSectionHeader(const char* title)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetSectionHeader title=%s", title);
+    
+    isSectionHeader_ = true;
+    isConnected_ = false;
+    
+    // 设置标题文字
+    nameLabel_.SetText(title);
+    nameLabel_.SetFont(DEFAULT_VECTOR_FONT_FILENAME, SECTION_FONT_SIZE);
+    nameLabel_.SetPosition(20, 0, 200, ITEM_HEIGHT);
+    nameLabel_.SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_BOTTOM,UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER);
+   
+    // 隐藏已连接指示
+    connectedIcon_.SetVisible(false);
+
+    borderImage_.SetVisible(false);
+    
+    Invalidate();
+}
+
+void ThunderBirdBlueDeviceItemView::SetSelected(bool selected)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetSelected=%d isSectionHeader=%d", selected, isSectionHeader_);
+    
+    isSelected_ = selected;
+    
+    if (isSectionHeader_) {
+        // 分组标题不显示选中状态
+        borderImage_.SetVisible(false);
+        return;
+    }
+    
+    if (selected) {
+        // 选中状态:显示橙色边框
+        borderImage_.SetVisible(true);
+    } else {
+        // 非选中状态:无边框
+        borderImage_.SetVisible(false);
+    }
+    
+    Invalidate();
+}
+
+BluetoothCaseInfo* ThunderBirdBlueDeviceItemView::GetDeviceInfo(void)
+{
+    return &deviceInfo_;
+}
+
+//========================================
+// ThunderBirdBlueListAdapter 实现
+//========================================
+
+ThunderBirdBlueListAdapter::ThunderBirdBlueListAdapter()
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdBlueListAdapter create");
+    RefreshDeviceData();
+}
+
+ThunderBirdBlueListAdapter::~ThunderBirdBlueListAdapter()
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdBlueListAdapter destroy");
+    displayList_.clear();
+    if (itemView_ != nullptr) {
+        delete itemView_;
+        itemView_ = nullptr;
+    }
+}
+
+void ThunderBirdBlueListAdapter::RefreshDeviceData()
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RefreshDeviceData");
+    BuildDisplayList();
+    
+    // 如果列表不为空且没有选中项,默认选中第一个设备项
+    if (!displayList_.empty() && selectedIndex_ < 0) {
+        selectedIndex_ = FindNextSelectableIndex(-1, true);
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Default selectedIndex=%d", selectedIndex_);
+    }
+}
+
+void ThunderBirdBlueListAdapter::BuildDisplayList()
+{
+    displayList_.clear();
+    
+    BluetoothModel* btModel = BluetoothModel::GetInstance();
+    if (btModel == nullptr) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BluetoothModel nullptr");
+        return;
+    }
+    
+    // 获取最后连接的设备地址
+    bd_addr_t* lastConnedAddr = btModel->GetLastConnedAddr();
+    bool hasConnectedDevice = false;
+    
+    // 检查是否有已连接的设备
+    if (lastConnedAddr != nullptr) {
+        // 检查地址是否为全0(表示没有连接)
+        bool isValidAddr = false;
+        for (int i = 0; i < BD_ADDR_LEN; i++) {
+            if (lastConnedAddr->addr[i] != 0) {
+                isValidAddr = true;
+                break;
+            }
+        }
+        if (isValidAddr && bt_is_acl_connected(lastConnedAddr)) {
+            hasConnectedDevice = true;
+        }
+    }
+    
+    // 获取扫描到的设备列表
+    std::list<BluetoothCaseInfo>& scanDevices = btModel->GetCase();
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "scanDevices size=%d hasConnected=%d", 
+                  scanDevices.size(), hasConnectedDevice);
+    
+    // 构建显示列表
+    uint16_t connectedCount = 0;
+    uint16_t nearbyCount = 0;
+    
+    // 1. 添加已连接设备分组(如果有已连接设备)
+    if (hasConnectedDevice) {
+        DeviceListItem headerItem;
+        headerItem.type = DeviceItemType::SECTION_HEADER_CONNECTED;
+        headerItem.isSelected = false;
+        displayList_.push_back(headerItem);
+        
+        // 添加已连接的设备
+        for (auto& device : scanDevices) {
+            if (connectedCount >= MAX_CONNECTED_DEVICES) {
+                break;
+            }
+            
+            // 检查设备是否已连接
+            if (bt_is_acl_connected((const bd_addr_t*)&device.addr)) {
+                DeviceListItem item;
+                item.type = DeviceItemType::DEVICE_CONNECTED;
+                item.deviceInfo = device;
+                item.isSelected = false;
+                displayList_.push_back(item);
+                connectedCount++;
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Added connected device: %s", device.deviceName);
+            }
+        }
+    }
+    
+    // 2. 添加附近设备分组
+    DeviceListItem nearbyHeader;
+    nearbyHeader.type = DeviceItemType::SECTION_HEADER_NEARBY;
+    nearbyHeader.isSelected = false;
+    displayList_.push_back(nearbyHeader);
+    
+    // 3. 添加附近的设备(未连接的)
+    for (auto& device : scanDevices) {
+        if (nearbyCount >= MAX_NEARBY_DEVICES) {
+            break;
+        }
+        
+        // 跳过已连接的设备
+        if (bt_is_acl_connected((const bd_addr_t*)&device.addr)) {
+            continue;
+        }
+        
+        DeviceListItem item;
+        item.type = DeviceItemType::DEVICE_NEARBY;
+        item.deviceInfo = device;
+        item.isSelected = false;
+        displayList_.push_back(item);
+        nearbyCount++;
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Added nearby device: %s", device.deviceName);
+    }
+    
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BuildDisplayList done: connected=%d, nearby=%d, total=%d",
+                  connectedCount, nearbyCount, displayList_.size());
+}
+
+uint16_t ThunderBirdBlueListAdapter::GetCount()
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetCount=%d", displayList_.size());
+    return static_cast<uint16_t>(displayList_.size());
+}
+
+UIView* ThunderBirdBlueListAdapter::GetView(UIView* inView, int16_t index)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetView index=%d inView=%p listSize=%d", 
+                  index, inView, displayList_.size());
+    
+    if (index < 0 || index >= static_cast<int16_t>(displayList_.size())) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetView index out of range!");
+        return nullptr;
+    }
+    
+    ThunderBirdBlueDeviceItemView* item = nullptr;
+    
+    if (inView == nullptr) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Creating new item view");
+        item = new ThunderBirdBlueDeviceItemView();
+        if (item == nullptr) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetView new item failed!");
+            return nullptr;
+        }
+    } else {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Reusing existing item view");
+        item = static_cast<ThunderBirdBlueDeviceItemView*>(inView);
+    }
+    
+    // 获取对应索引的数据
+    auto it = displayList_.begin();
+    std::advance(it, index);
+    
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetView type=%d", static_cast<int>(it->type));
+    
+    switch (it->type) {
+        case DeviceItemType::SECTION_HEADER_CONNECTED:
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Setting SECTION_HEADER_CONNECTED");
+            item->SetSectionHeader("我的设备");
+            break;
+        case DeviceItemType::SECTION_HEADER_NEARBY:
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Setting SECTION_HEADER_NEARBY");
+            item->SetSectionHeader("附近的设备");
+            break;
+        case DeviceItemType::DEVICE_CONNECTED:
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Setting DEVICE_CONNECTED: %s", it->deviceInfo.deviceName);
+            item->SetDeviceInfo(it->deviceInfo, true);
+            item->SetSelected(index == selectedIndex_);
+            break;
+        case DeviceItemType::DEVICE_NEARBY:
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Setting DEVICE_NEARBY: %s", it->deviceInfo.deviceName);
+            item->SetDeviceInfo(it->deviceInfo, false);
+            item->SetSelected(index == selectedIndex_);
+            break;
+        default:
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Unknown type!");
+            break;
+    }
+    
+    item->SetViewIndex(index);
+    
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetView done, returning item=%p", item);
+    return item;
+}
+
+bool ThunderBirdBlueListAdapter::IsDeviceItem(int16_t index) const
+{
+    if (index < 0 || index >= static_cast<int16_t>(displayList_.size())) {
+        return false;
+    }
+    
+    auto it = displayList_.begin();
+    std::advance(it, index);
+    
+    return (it->type == DeviceItemType::DEVICE_CONNECTED || 
+            it->type == DeviceItemType::DEVICE_NEARBY);
+}
+
+int16_t ThunderBirdBlueListAdapter::FindNextSelectableIndex(int16_t currentIndex, bool forward)
+{
+    if (displayList_.empty()) {
+        return -1;
+    }
+    
+    int16_t listSize = static_cast<int16_t>(displayList_.size());
+    int16_t nextIndex = currentIndex;
+    
+    // 查找下一个可选的设备项
+    for (int16_t i = 0; i < listSize; i++) {
+        if (forward) {
+            nextIndex++;
+            if (nextIndex >= listSize) {
+                nextIndex = 0;  // 循环到开头
+            }
+        } else {
+            nextIndex--;
+            if (nextIndex < 0) {
+                nextIndex = listSize - 1;  // 循环到末尾
+            }
+        }
+        
+        if (IsDeviceItem(nextIndex)) {
+            return nextIndex;
+        }
+    }
+    
+    return -1;  // 没有找到可选项
+}
+
+void ThunderBirdBlueListAdapter::SelectNext()
+{
+    int16_t newIndex = FindNextSelectableIndex(selectedIndex_, true);
+    if (newIndex >= 0 && newIndex != selectedIndex_) {
+        selectedIndex_ = newIndex;
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SelectNext: selectedIndex=%d", selectedIndex_);
+    }
+    else
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "没有可选择的设备");
+    }
+}
+
+void ThunderBirdBlueListAdapter::SelectPrevious()
+{
+    int16_t newIndex = FindNextSelectableIndex(selectedIndex_, false);
+    if (newIndex >= 0 && newIndex != selectedIndex_) {
+        selectedIndex_ = newIndex;
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SelectPrevious: selectedIndex=%d", selectedIndex_);
+    }
+    else
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "没有可选择的设备");
+    }
+}
+
+void ThunderBirdBlueListAdapter::SetSelectedIndex(int16_t index)
+{
+    if (IsDeviceItem(index)) {
+        selectedIndex_ = index;
+    }
+}
+
+BluetoothCaseInfo* ThunderBirdBlueListAdapter::GetSelectedDevice()
+{
+    if (selectedIndex_ < 0 || selectedIndex_ >= static_cast<int16_t>(displayList_.size())) {
+        return nullptr;
+    }
+    
+    auto it = displayList_.begin();
+    std::advance(it, selectedIndex_);
+    
+    if (it->type == DeviceItemType::DEVICE_CONNECTED || 
+        it->type == DeviceItemType::DEVICE_NEARBY) {
+        return &(it->deviceInfo);
+    }
+    
+    return nullptr;
+}
+
+uint16_t ThunderBirdBlueListAdapter::GetDeviceCount() const
+{
+    uint16_t count = 0;
+    for (const auto& item : displayList_) {
+        if (item.type == DeviceItemType::DEVICE_CONNECTED || 
+            item.type == DeviceItemType::DEVICE_NEARBY) {
+            count++;
+        }
+    }
+    return count;
+}
+
+} // namespace OHOS
index c3af0eb..5ff9d4c 100644 (file)
@@ -1,10 +1,12 @@
 #include "thunderbird/include/ThunderBirdBlueView.h"
 #include "thunderbird/include/ThunderBirdMainView.h"
+#include "thunderbird/include/ThunderBirdBlueListAdapter.h"
 #include "wearable_log.h"
 #include "common/image_cache_manager.h"
 #include "custom_utils.h"
 #include "vibrator_service.h"
 #include "bluetooth/Ln_Bluetooth_apiC.h"
+#include "bluetooth/BluetoothModel.h"
 
 
 namespace OHOS
@@ -47,6 +49,7 @@ namespace OHOS
         if (RemindIcon3 != nullptr) { delete RemindIcon3; RemindIcon3 = nullptr; }
         if (BackGround != nullptr) { delete BackGround; BackGround = nullptr; }
         if (DeviceList != nullptr) { delete DeviceList; DeviceList = nullptr; }
+        if (deviceListAdapter_ != nullptr) { delete deviceListAdapter_; deviceListAdapter_ = nullptr; }
     }
 
     bool ThunderBirdBlueView::EnsureNetAnimator()
@@ -55,6 +58,18 @@ namespace OHOS
         return true;
     }
 
+    void ThunderBirdBlueView::InitDeviceListAdapter(void)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdBlueView::InitDeviceListAdapter");
+        if (deviceListAdapter_ == nullptr) {
+            deviceListAdapter_ = new ThunderBirdBlueListAdapter();
+            if (deviceListAdapter_ == nullptr) {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdBlueListAdapter create failed");
+                return;
+            }
+        }
+    }
+
     UIViewGroup *ThunderBirdBlueView::ThunderBirdBlueViewInit(void)
     {
         group = new UIViewGroup();
@@ -157,28 +172,33 @@ namespace OHOS
         DeviceList = new UIList(UIList::VERTICAL);
         if (DeviceList)
         {
-            DeviceList->SetPosition(30, 160, 300, 100);
-            DeviceList->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);
-            DeviceList->SetDragACCLevel(5);
-            DeviceList->SetSwipeACCLevel(200);
-            DeviceList->SetReboundSize(30);
-            DeviceList->SetVisible(false);
+            DeviceList->SetPosition(60, 90, 240, 150);  // 调整位置和大小以适应圆形屏幕
+            DeviceList->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);  // 透明背景
             group->Add(DeviceList);
         }
+        
+        // 初始化设备列表适配器
+        InitDeviceListAdapter();
+        
         return group;
     }
 
     void ThunderBirdBlueView::Show(int16_t showView)
     {
         if (group == nullptr) { return; }
+        currentShowView_ = showView;
+        
         if (TextLabel) { TextLabel->SetVisible(false);}
+        if (TextLabel_2) { TextLabel_2->SetVisible(false);}
         if (RemindLabel) { RemindLabel->SetVisible(false);}
+        if (RemindLabel_2) { RemindLabel_2->SetVisible(false);}
+        if (RemindLabel_3) { RemindLabel_3->SetVisible(false);}
         if (RemindIcon) { RemindIcon->SetVisible(false); }
-        if (RemindIcon2) { RemindIcon2->SetVisible(false); }
         if (RemindIcon1) { RemindIcon1->SetVisible(false); }
         if (RemindIcon2) { RemindIcon2->SetVisible(false); }
         if (RemindIcon3) { RemindIcon3->SetVisible(false); }
         if (DeviceList) { DeviceList->SetVisible(false); }
+        
         switch (showView)
         {
         case THUNDERBIRD_BULEVIEW_ENTER:
@@ -332,60 +352,70 @@ namespace OHOS
         }
         case THUNDERBIRD_BULEVIEW_DEVICE_LIST:
         {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Show DEVICE_LIST view");
+            
+            // 不显示标题(列表中已有分组标题)
             if (TextLabel)
             {
-                TextLabel->SetPosition(112, 60, 180, 42);
-                TextLabel->SetText("附近的设备");
-                TextLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
-                TextLabel->SetVisible(true);
+                TextLabel->SetVisible(false);
             } 
             if (TextLabel_2)
             {
                 TextLabel_2->SetVisible(false);
             } 
+            
             // 显示设备列表
-            if (DeviceList)
-            {
-                DeviceList->SetPosition(30, 120, 300, 120);
+            if (DeviceList != nullptr && deviceListAdapter_ != nullptr)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Setting up DeviceList");
+                
+                // 刷新设备列表数据
+                deviceListAdapter_->RefreshDeviceData();
+                // 确保适配器已设置
+                DeviceList->SetAdapter(deviceListAdapter_);
+                DeviceList->SetStartIndex(0);
+                DeviceList->SetPosition(60, 70, 240, 170);  // 调整位置
                 DeviceList->SetVisible(true);
+                DeviceList->RefreshList();
+                
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DeviceList visible, count=%d", 
+                              deviceListAdapter_->GetCount());
+            }
+            else
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DeviceList or adapter is null!");
             }
             if (RemindLabel)
             {
-                RemindLabel->SetPosition(44, 275, 272, 25);
-                RemindLabel->SetText("按 +/- 选择");
+                RemindLabel->SetPosition(44, 260, 272, 25);
+                RemindLabel->SetText("按 +/- 选择    按     确认");
                 RemindLabel->SetVisible(true);
             }
             if (RemindLabel_2)
             {
-                RemindLabel_2->SetPosition(109, 310, 142, 25);
-                RemindLabel_2->SetText("按     确认");
+                RemindLabel_2->SetPosition(109, 285, 142, 25);
+                RemindLabel_2->SetText("长按     退出配对");
                 RemindLabel_2->SetVisible(true);
             }
-            if (RemindLabel_3)
-            {
-                RemindLabel_3->SetPosition(109, 335, 142, 25);
-                RemindLabel_3->SetText("长按     退出配对");
-                RemindLabel_3->SetVisible(true);
-            }
             if (RemindIcon)
             {
                 RemindIcon->SetVisible(false);
             }
             if (RemindIcon1)
             {
-                RemindIcon1->SetPosition(68, 277, 22, 22);
+                RemindIcon1->SetPosition(68, 262, 22, 22);
                 RemindIcon1->SetSrc("/user/res/volume_up.bin");
                 RemindIcon1->SetVisible(true);
             }
             if (RemindIcon2)
             {
-                RemindIcon2->SetPosition(216, 277, 22, 22);
+                RemindIcon2->SetPosition(183, 262, 22, 22);
                 RemindIcon2->SetSrc("/user/res/volume_up.bin");
                 RemindIcon2->SetVisible(true);
             }
             if (RemindIcon3)
             {
-                RemindIcon3->SetPosition(151, 312, 22, 22);
+                RemindIcon3->SetPosition(151, 287, 22, 22);
                 RemindIcon3->SetSrc("/user/res/volume_up.bin");
                 RemindIcon3->SetVisible(true);
             }
@@ -411,13 +441,13 @@ namespace OHOS
             } 
             if (RemindLabel)
             {
-                RemindLabel->SetPosition(44, 275, 272, 25);
-                RemindLabel->SetText("按     返回列表    长按     断开连接");
+                RemindLabel->SetPosition(44, 260, 272, 25);
+                RemindLabel->SetText("按 +/- 选择    按     连接");
                 RemindLabel->SetVisible(true);
             }
             if (RemindLabel_2)
             {
-                RemindLabel_2->SetPosition(109, 310, 142, 25);
+                RemindLabel_2->SetPosition(109, 285, 142, 25);
                 RemindLabel_2->SetText("长按     退出配对");
                 RemindLabel_2->SetVisible(true);
             }
@@ -429,19 +459,19 @@ namespace OHOS
             }
             if (RemindIcon1)
             {
-                RemindIcon1->SetPosition(68, 277, 22, 22);
+                RemindIcon1->SetPosition(68, 262, 22, 22);
                 RemindIcon1->SetSrc("/user/res/volume_up.bin");
                 RemindIcon1->SetVisible(true);
             }
             if (RemindIcon2)
             {
-                RemindIcon2->SetPosition(216, 277, 22, 22);
+                RemindIcon2->SetPosition(183, 262, 22, 22);
                 RemindIcon2->SetSrc("/user/res/volume_up.bin");
                 RemindIcon2->SetVisible(true);
             }
             if (RemindIcon3)
             {
-                RemindIcon3->SetPosition(151, 312, 22, 22);
+                RemindIcon3->SetPosition(151, 287, 22, 22);
                 RemindIcon3->SetSrc("/user/res/volume_up.bin");
                 RemindIcon3->SetVisible(true);
             }
@@ -577,6 +607,7 @@ namespace OHOS
         HandleBluetoothViewOperation(showView);
         return;
     }
+    
     void ThunderBirdBlueView::UpdateTaskReminderText(const char* text)
     {
         if (TextLabel) { TextLabel->SetText(text); }
@@ -584,12 +615,129 @@ namespace OHOS
     
     void ThunderBirdBlueView::RefreshDeviceList(void)
     {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RefreshDeviceList called");
+        
         if (DeviceList == nullptr) {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BluetoothEarListView nullptr");
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DeviceList nullptr!");
+            return;
+        }
+        
+        if (deviceListAdapter_ == nullptr) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "deviceListAdapter_ nullptr!");
+            return;
+        }
+        
+        // 刷新适配器数据
+        deviceListAdapter_->RefreshDeviceData();
+        
+        // 确保适配器已设置
+        DeviceList->SetAdapter(deviceListAdapter_);
+        DeviceList->RefreshList();
+        
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RefreshDeviceList done, count=%d", 
+                      deviceListAdapter_->GetCount());
+    }
+    
+    void ThunderBirdBlueView::UpdateDeviceListSelection(void)
+    {
+        if (DeviceList == nullptr || deviceListAdapter_ == nullptr) {
             return;
         }
+        
+        // 刷新列表以更新选中状态显示
         DeviceList->RefreshList();
+        int16_t selectedIndex = deviceListAdapter_->GetSelectedIndex();
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateDeviceListSelection: selectedIndex=%d", selectedIndex);
     }
+    
+    // 按键操作:选择上一个设备(音量+键)
+    void ThunderBirdBlueView::OnKeyUp(void)
+    {
+        if (currentShowView_ != THUNDERBIRD_BULEVIEW_DEVICE_LIST) {
+            return;
+        }
+        
+        if (deviceListAdapter_ == nullptr) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "deviceListAdapter_ nullptr");
+            return;
+        }
+        
+        deviceListAdapter_->SelectPrevious();
+        UpdateDeviceListSelection();
+        
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OnKeyUp: selected=%d", 
+                      deviceListAdapter_->GetSelectedIndex());
+    }
+    
+    // 按键操作:选择下一个设备(音量-键)
+    void ThunderBirdBlueView::OnKeyDown(void)
+    {
+        if (currentShowView_ != THUNDERBIRD_BULEVIEW_DEVICE_LIST) {
+            return;
+        }
+        
+        if (deviceListAdapter_ == nullptr) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "deviceListAdapter_ nullptr");
+            return;
+        }
+        
+        deviceListAdapter_->SelectNext();
+        UpdateDeviceListSelection();
+        
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OnKeyDown: selected=%d", 
+                      deviceListAdapter_->GetSelectedIndex());
+    }
+    
+    // 按键操作:确认连接选中的设备
+    void ThunderBirdBlueView::OnKeyConfirm(void)
+    {
+        if (currentShowView_ != THUNDERBIRD_BULEVIEW_DEVICE_LIST) {
+            return;
+        }
+        
+        if (deviceListAdapter_ == nullptr) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "deviceListAdapter_ nullptr");
+            return;
+        }
+        
+        BluetoothCaseInfo* selectedDevice = deviceListAdapter_->GetSelectedDevice();
+        if (selectedDevice == nullptr) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "No device selected");
+            return;
+        }
+        
+        WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "OnKeyConfirm: connecting to %s", 
+                      selectedDevice->deviceName);
+        
+        // 设置临时MAC值并发起连接
+        BluetoothModel::GetInstance()->SetTempMacValue(selectedDevice);
+        BluetoothModel::GetInstance()->SetTagScanDeviceClicked(true);
+        
+        // 发起连接
+        int ret = BluetoothModel::GetInstance()->ConnectRemoteDevice(
+            (const bd_addr_t*)&selectedDevice->addr);
+        
+        if (ret != 0) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ConnectRemoteDevice failed: %d", ret);
+            // 可以在这里显示连接失败提示
+            if(ThunderBirdMainView::GetInstance()) {
+                int currentView = ThunderBirdMainView::GetInstance()->GetCurrentView();
+                ThunderBirdMainView::GetInstance()->ChangeView(currentView, 
+                    THUNDERBIRD_BLUEVIEW, 
+                    ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_CONNECT_FAILED);
+            }
+        }
+    }
+    
+    // 获取当前选中的设备索引
+    int16_t ThunderBirdBlueView::GetSelectedDeviceIndex(void) const
+    {
+        if (deviceListAdapter_ == nullptr) {
+            return -1;
+        }
+        return deviceListAdapter_->GetSelectedIndex();
+    }
+    
     // 处理蓝牙视图操作
     void ThunderBirdBlueView::HandleBluetoothViewOperation(int16_t view)
     {
index 5736366..6d16222 100644 (file)
@@ -345,6 +345,31 @@ namespace OHOS
         //     }
         //     return true;
         // }
+
+        // 处理设备列表功能
+        if (keyState == InputDevice::STATE_RELEASE && screenState == 0 )
+        {
+            if(currentView == THUNDERBIRD_BLUEVIEW )
+            {
+                if(currentSubView == ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_DEVICE_LIST)
+                {
+                    // 处理设备列表功能
+                    if(ThunderBirdBlueView::GetInstance())
+                        ThunderBirdBlueView::GetInstance()->OnKeyConfirm();// 点击确认键:确认选择当前设备
+                }
+                else if(currentSubView == ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_CONNECT_SUCCESS)
+                {
+                    //跳转到断连询问界面
+                    ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_BLUEVIEW, ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_DISCONNECT_CONFIRM);
+                }
+                else if(currentSubView == ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_DISCONNECT_CONFIRM)
+                {
+                    //执行断连操作
+                    ThunderBirdBlueView::GetInstance()->ExecuteDisconnect();
+                }
+            }
+            return true;
+        }
         
         // 短按FUNC键(息屏状态下)
         if (keyState == InputDevice::STATE_PRESS && screenState == 0 ) {
@@ -816,13 +841,8 @@ namespace OHOS
                     //蓝牙已断开,返回搜索界面,提示用户重新搜索
                     ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_STATUS_SHOW);
                     break;
-                case ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_CONNECT_SUCCESS:
-                    //跳转到断连询问界面
-                    ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_BLUEVIEW, ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_DISCONNECT_CONFIRM);
-                    break;
-                case ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_DISCONNECT_CONFIRM:
-                    //执行断连操作
-                    ThunderBirdBlueView::GetInstance()->ExecuteDisconnect();
+                case ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_DEVICE_LIST:
+                    ThunderBirdBlueView::GetInstance()->OnKeyUp();// 音量+键:选择上一个设备
                     break;
             }
         }
@@ -841,6 +861,9 @@ namespace OHOS
                     //返回设备列表
                     ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_BLUEVIEW, ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_DEVICE_LIST);
                     break;
+                case ThunderBirdBlueView::THUNDERBIRD_BULEVIEW_DEVICE_LIST:
+                    ThunderBirdBlueView::GetInstance()->OnKeyDown();// 音量-键:选择下一个设备
+                    break;
             }
         }
         else if(keyType == KEY_TYPE_FUNC)
index 4fb245d..2c5bb2b 100644 (file)
@@ -1660,8 +1660,8 @@ static uint32_t ln_bluetooth_status_report_at(uint8_t *para, uint32_t paraLen, c
     }
     printf("+LN_BLUETOOTH_STATUS_REPORT: OK\n");
     printf("[LN][BLUETOOTH_STATUS_REPORT] bluetoothStatus=%s\n", bluetoothStatus);
-    do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_BLUETOOTH_STATUS_REPORT, bluetoothStatus, strlen(bluetoothStatus));
-    // push_bluetooth_connect_notification(bluetoothStatus);
+    // do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_BLUETOOTH_STATUS_REPORT, bluetoothStatus, strlen(bluetoothStatus));
+    push_bluetooth_connect_notification(bluetoothStatus);
     return ERRCODE_SUCC;
 }
 /* 格式化打印蓝牙地址 */