人工智能

HarmonyOS Sample之Bluetooth传统蓝牙的使用

时间:2010-12-5 17:23:32  作者:IT科技类资讯   来源:人工智能  查看:  评论:0
内容摘要:想了解更多内容,请访问:和华为官方合作共建的鸿蒙技术社区https://harmonyos.51cto.com1.介绍本示例演示了如何对蓝牙进行基本操作,传统蓝牙本机管理:主要是针对蓝牙本机的基本操作

想了解更多内容,统蓝请访问:

和华为官方合作共建的使用鸿蒙技术社区

https://harmonyos.51cto.com

1.介绍

本示例演示了如何对蓝牙进行基本操作,

传统蓝牙本机管理:

主要是统蓝针对蓝牙本机的基本操作,包括:打开和关闭蓝牙、使用设置和获取本机蓝牙名称、统蓝扫描和取消扫描周边蓝牙设备、使用获取本机蓝牙profile对其他设备的统蓝连接状态、获取本机蓝牙已配对的使用蓝牙设备列表。

传统蓝牙远端管理操作:

主要是统蓝针对远端蓝牙设备的基本操作,包括:获取远端蓝牙设备地址、使用类型、统蓝名称和配对状态,使用以及向远端设备发起配对。统蓝

传统蓝牙和BLE的使用的概念请参考 蓝牙开发概述

还有一个小知识点,

调用蓝牙的统蓝打开接口需要ohos.permission.USE_BLUETOOTH权限,

调用蓝牙扫描接口需要ohos.permission.LOCATION权限和ohos.permission.DISCOVER_BLUETOOTH权限。

2.搭建环境

安装DevEco Studio,详情请参考DevEco Studio下载。

设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:

如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。亿华云计算

如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境。

下载源码后,使用DevEco Studio 打开项目,模拟器运行即可。

真机运行需要将config.json中的buddleName修改为自己的,如果没有请到AGC上进行配置,参见 使用模拟器进行调试 。

3.代码结构

4.实例讲解

4.1.界面布局

 布局效果

4.2.后台代码

4.2.1 涉及的相关类

SDK提供的核心类:

BluetoothHost.java//蓝牙主机,可以管理蓝牙,提供了蓝牙的基本操作,打开/关闭/获取状态等。

BluetoothRemoteDevice.java//蓝牙对象,用于建立与对端设备的连接并查询名称、设备类型和配对状态等信息。

自定义的类:

BluetoothItemProvider.java//蓝牙设备列表项提供程序

BluetoothEventListener.java//蓝牙事件监听接口

BluetoothPlugin.java//蓝牙插件

BluetoothDevice.java//蓝牙对象简易模型

4.2.2 BluetoothPlugin.java 蓝牙插件提供的功能

a.初始化BluetoothHost蓝牙主机对象getDefaultHost

/** * 初始化蓝牙主机对象和监听器 * Initializes the Bluetooth Host on device. * @param eventListener interface to update the Bluwettoth events */ public void initializeBluetooth(BluetoothEventListener eventListener) {    bluetoothEventListener = eventListener;   btHost = BluetoothHost.getDefaultHost(mainSliceContext);   LogUtil.info(TAG, "initializeBluetooth, btHost:"+btHost); } 

b.开启/关闭蓝牙/获取蓝牙状态enableBt/disableBt/getBtState

/** * 开启蓝牙 * 低功耗蓝牙(BLE ,Bluetooth Low Energy),LE是2010年才提出的 * 经典蓝牙(classic Bluetooth),包括BR,EDR和HS(AMP)三种模式 * Enables the Bluetooth on device. */ public void enableBluetooth() {    LogUtil.info("enableBluetooth", "getBtState:"+btHost.getBtState());   //获取蓝牙主机的状态   if (btHost.getBtState() == STATE_OFF ||           btHost.getBtState() == STATE_TURNING_OFF ||           btHost.getBtState() ==STATE_BLE_ON) {        LogUtil.info("enableBluetooth", "enableBt:"+btHost.getBtState());       //开启蓝牙       btHost.enableBt();   }   //事件通知蓝牙状态发生改变   bluetoothEventListener.notifyBluetoothStatusChanged(btHost.getBtState()); } /** * 关闭蓝牙 * Disables the Bluetooth on device. */ public void disableBluetooth() {    if (btHost.getBtState() == STATE_ON || btHost.getBtState() == STATE_TURNING_ON) {        btHost.disableBt();   }   bluetoothEventListener.notifyBluetoothStatusChanged(btHost.getBtState()); } /** * 获取蓝牙状态 * Obtains the status of the Bluetooth on device. * @return status of Bluetooth on device */ public int getBluetoothStatus() {    LogUtil.info("getBluetoothStatus", "getBluetoothStatus:"+btHost.getBtState());   //获取蓝牙状态   return btHost.getBtState(); } 

c.开始蓝牙发现startBtDiscovery

还要注意的是蓝牙发现操作需要申请位置权限。

/** * 开始蓝牙发现 * Scans the currently available bluetooth devices */ public void startBtDiscovery() {    if (!btHost.isBtDiscovering()) {        //开始发现设备,大约需要12.8s       btHost.startBtDiscovery();   } } /** *判断是否有权限 */ private boolean hasPermission() {    return mainSliceContext.verifySelfPermission(Constants.PERM_LOCATION) == IBundleManager.PERMISSION_GRANTED; } /** * 启动蓝牙扫描 * Scans the currently available bluetooth devices */ public void startBtScan() {    LogUtil.info("startBtScan", "getBtState:"+btHost.getBtState());   int btStatus = btHost.getBtState();   if (btStatus == STATE_ON) {        if (hasPermission()) {            startBtDiscovery();       } else {            requestPermission();       }   } } 

d.蓝牙设备配对及获取已配对的源码库设备列表startPair/getPairedDevices

/** * 启动与给定地址的蓝牙设备配对。 * initiate pairing with bluetooth device of given address. * @param pairAddress address of the bluetooth device */ public void startPair(String pairAddress) {    Optional<BluetoothRemoteDevice> optBluetoothDevice = getSelectedDevice(pairAddress);   optBluetoothDevice.ifPresent(BluetoothRemoteDevice::startPair); } /** * 获取要配对的设备 * @param pairAddress * @return */ private Optional<BluetoothRemoteDevice> getSelectedDevice(String pairAddress) {    if (pairAddress != null && !pairAddress.isEmpty()) {        for (BluetoothRemoteDevice device : availableDevices) {            if (device.getDeviceAddr().equals(pairAddress)) {                return Optional.ofNullable(device);           }       }   }   return Optional.empty(); } /** * 获取已配对的蓝牙设备列表 * Obtains the paired Bluetooth device list. * @return paired Bluetooth devices */ public List<BluetoothDevice> getPairedDevices() {    //btHost.getPairedDevices()   Set<BluetoothRemoteDevice> pairedDevices = new HashSet<>(btHost.getPairedDevices());   return getBluetoothDevices(pairedDevices); } 

e.蓝牙事件的订阅/取消 及 相关事件的处理

在处理蓝牙事件的同时,通过BluetoothEventListener通知MainAbilitySlice。

/** * 订阅蓝牙事件 * Subscribe for Events of Bluetooth using CommonEvents */ public void subscribeBluetoothEvents() {    MatchingSkills matchingSkills = new MatchingSkills();   //表示蓝牙状态改变时上报的事件。   matchingSkills.addEvent(BluetoothHost.EVENT_HOST_STATE_UPDATE);   //指示蓝牙扫描开始时报告的事件。   matchingSkills.addEvent(BluetoothHost.EVENT_HOST_DISCOVERY_STARTED);   //指示蓝牙扫描完成时报告的事件。   matchingSkills.addEvent(BluetoothHost.EVENT_HOST_DISCOVERY_FINISHED);   //表示发现远程蓝牙设备时上报的事件。   matchingSkills.addEvent(BluetoothRemoteDevice.EVENT_DEVICE_DISCOVERED);   //远程蓝牙设备配对时上报的事件。   matchingSkills.addEvent(BluetoothRemoteDevice.EVENT_DEVICE_PAIR_STATE);   //用于创建 CommonEventSubscriber 实例并传递 subscribeInfo 参数的构造函数。   CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);   //订阅者   commonEventSubscriber = new CommonEventSubscriber(subscribeInfo) {        @Override       public void onReceiveEvent(CommonEventData commonEventData) {            Intent intent = commonEventData.getIntent();           handleIntent(intent);       }   };   try {        //完成订阅       CommonEventManager.subscribeCommonEvent(commonEventSubscriber);   } catch (RemoteException e) {        LogUtil.error(TAG, "RemoteException while subscribe bluetooth events.");   } } /** * 取消订阅蓝牙事件 * UnSubscribe for Bluetooth Events */ public void unSubscribeBluetoothEvents() {    if (commonEventSubscriber != null) {        try {            CommonEventManager.unsubscribeCommonEvent(commonEventSubscriber);       } catch (RemoteException e) {            LogUtil.error(TAG, "RemoteException while unsubscribing bluetooth events.");       }       commonEventSubscriber = null;   } } private void handleIntent(Intent intent) {    if (intent == null) {        return;   }   String action = intent.getAction();   switch (action) {        //状态更新       case BluetoothHost.EVENT_HOST_STATE_UPDATE:           handleHostStateUpdate();           break;       //扫描开始       case BluetoothHost.EVENT_HOST_DISCOVERY_STARTED:           handleDeviceDiscoveryState(true);           break;       //表示发现远程蓝牙设备时上报的事件。       case BluetoothRemoteDevice.EVENT_DEVICE_DISCOVERED:           handleBluetoothDeviceDiscovered(intent);           break;       // 扫描完成       case BluetoothHost.EVENT_HOST_DISCOVERY_FINISHED:           handleDeviceDiscoveryState(false);           break;       //表示远程蓝牙设备配对时上报的事件。       case BluetoothRemoteDevice.EVENT_DEVICE_PAIR_STATE:           handleDevicePairState(intent);           break;       default:           LogUtil.info(TAG, "Action not handled : " + action);   } } private void handleDevicePairState(Intent intent) {    BluetoothRemoteDevice btRemoteDevice = intent.getSequenceableParam(BluetoothRemoteDevice.REMOTE_DEVICE_PARAM_DEVICE);   if (btRemoteDevice.getPairState() == BluetoothRemoteDevice.PAIR_STATE_PAIRED) {        //更新2个设备列表       updateAvailableDeviceList(btRemoteDevice);       updatePairedDeviceList();   } } private void handleDeviceDiscoveryState(boolean isStarted) {    //处理扫描状态变化事件通知   bluetoothEventListener.notifyDiscoveryState(isStarted); } /** * 处理蓝牙状态变化通知 */ private void handleHostStateUpdate() {    int status = getBluetoothStatus();   bluetoothEventListener.notifyBluetoothStatusChanged(status); } /** * 处理蓝牙发现事件 * @param intent */ private void handleBluetoothDeviceDiscovered(Intent intent) {    BluetoothRemoteDevice btRemoteDevice =           intent.getSequenceableParam(BluetoothRemoteDevice.REMOTE_DEVICE_PARAM_DEVICE);   //未配对的设备   if (btRemoteDevice.getPairState() != BluetoothRemoteDevice.PAIR_STATE_PAIRED) {        //发现后添加到可用的蓝牙设备       availableDevices.add(btRemoteDevice);   }   bluetoothEventListener.updateAvailableDevices(getAvailableDevices()); } /** * 更新可用设备列表 * @param remoteDevice */ private void updateAvailableDeviceList(BluetoothRemoteDevice remoteDevice) {    //移除以配对的蓝牙   availableDevices.removeIf(device -> device.getDeviceAddr().equals(remoteDevice.getDeviceAddr()));   bluetoothEventListener.updateAvailableDevices(getAvailableDevices()); } private void updatePairedDeviceList() {    //刷新已配对的蓝牙列表   bluetoothEventListener.updatePairedDevices(getPairedDevices()); } public List<BluetoothDevice> getAvailableDevices() {    return getBluetoothDevices(availableDevices); } /** * 获取已配对的蓝牙设备列表 * Obtains the paired Bluetooth device list. * @return paired Bluetooth devices */ public List<BluetoothDevice> getPairedDevices() {    //btHost.getPairedDevices()   Set<BluetoothRemoteDevice> pairedDevices = new HashSet<>(btHost.getPairedDevices());   return getBluetoothDevices(pairedDevices); } private List<BluetoothDevice> getBluetoothDevices(Set<BluetoothRemoteDevice> remoteDeviceList) {    List<BluetoothDevice> btDevicesList = new ArrayList<>();   if (remoteDeviceList != null) {        //       btDevicesList = remoteDeviceList.stream().map(BluetoothDevice::new).collect(Collectors.toList());   }   return btDevicesList; } 

4.2.3 BluetoothEventListener.java 自定义的蓝牙事件监听器接口

public interface BluetoothEventListener {   void updateAvailableDevices(List<BluetoothDevice> bluetoothDevice);  void updatePairedDevices(List<BluetoothDevice> bluetoothDevice);  void notifyBluetoothStatusChanged(int bluetoothStatus);  void notifyDiscoveryState(boolean isStarted);  } 

4.2.4 BluetoothItemProvider.java 蓝牙设备列表提供程序

这个可以作为一个标准件了,每个ListContainer都可以用它,高防服务器包括了列表的通用操作,像数据更新,点击事件等。

public class BluetoothItemProvider extends BaseItemProvider {   private final AbilityContext context;  private List<BluetoothDevice> bluetoothDeviceList;  public BluetoothItemProvider(AbilityContext context, List<BluetoothDevice> itemList) {       this.context = context;      bluetoothDeviceList = itemList;  }  @Override  public int getCount() {       return bluetoothDeviceList.size();  }  @Override  public Object getItem(int position) {       return bluetoothDeviceList.get(position);  }  @Override  public long getItemId(int position) {       return position;  }  @Override  public Component getComponent(int position, Component component, ComponentContainer componentContainer) {       return getRootComponent(position);  }  private Component getRootComponent(int position) {       //List item 布局组件      Component rootComponent = LayoutScatter.getInstance(context)              .parse(ResourceTable.Layout_list_item, null, false);      Text deviceName = (Text) rootComponent.findComponentById(ResourceTable.Id_bluetooth_device_name);      //蓝牙设备名称      BluetoothDevice bluetoothDevice = bluetoothDeviceList.get(position);      deviceName.setText(bluetoothDevice.getName());      //设置点击监听事件,开始配对      rootComponent.setClickedListener(component -> {           LogUtil.info("BluetoothItemProvider", "startPair:" + bluetoothDevice.getAddress());          //表示对端设备未配对。          if (bluetoothDevice.getPairState() == BluetoothRemoteDevice.PAIR_STATE_NONE) {               //启动与给定地址的蓝牙设备配对。              BluetoothPlugin.getInstance(context).startPair(bluetoothDevice.getAddress());          }      });      return rootComponent;  }  /**   * 更新蓝牙设备列表   * updates available Bluetooth devices in UI   *   * @param devices list of Bluetooth devices   */  public void updateDeviceList(List<BluetoothDevice> devices) {       bluetoothDeviceList = devices;      notifyDataChanged();  } } 

4.2.5 MainAbilitySlice.java 主能力页面操作

a.首先是实现了几个相关的接口

Component.ClickedListener 用于实现按钮的点击事件

BluetoothEventListener 用于实现蓝牙事件通知的处理

CheckedStateChangedListener 用于实现switch开关的处理

public class MainAbilitySlice extends AbilitySlice     implements Component.ClickedListener, BluetoothEventListener, AbsButton.CheckedStateChangedListener {  

b.初始化工作

在onActive生命周期函数中

初始化蓝牙插件/初始化容器列表/初始化组件/订阅蓝牙事件

/** * 初始化蓝牙插件 */ private void initializeBluetoothHost() {    //   BluetoothPlugin.getInstance(this).initializeBluetooth(this); } private void initComponents() {    //开始发现 按钮,用来搜索附件的蓝牙设备   Button btnStartDiscovery = (Button) findComponentById(ResourceTable.Id_btn_start_discovery);   //因为implements Component.ClickedListener 所以可以这样写   btnStartDiscovery.setClickedListener(this);   initListContainer();   //蓝牙状态文本组件   textBluetoothStatus = (Text) findComponentById(ResourceTable.Id_bluetooth_status);   //蓝牙开关组件   bluetoothSwitch = (Switch) findComponentById(ResourceTable.Id_bt_switch);   //设置状态监听事件   bluetoothSwitch.setCheckedStateChangedListener(this);   //根据系统蓝牙状态设置开关   updateBluetoothStatus(BluetoothPlugin.getInstance(this).getBluetoothStatus());   //附件的蓝牙设备容器列表   containerLists = (DirectionalLayout) findComponentById(ResourceTable.Id_container_lists);   //根据蓝牙状态控制是否显示附件的蓝牙设备容器列表   containerLists.setVisibility(isBluetoothEnabled() ? Component.VISIBLE : Component.HIDE);   //环形进度条组件   progressBar = (ProgressBar) findComponentById(ResourceTable.Id_progressbar); } /** * 订阅蓝牙事件 */ private void subscribeBluetoothEvents() {    //   BluetoothPlugin.getInstance(this).subscribeBluetoothEvents(); } /** * 初始化容器列表 */ private void initListContainer() {    ListContainer availableDevicesContainer =       (ListContainer) findComponentById(ResourceTable.Id_list_available_devices);   //1.获取可用的蓝牙设备   availableDevicesItemProvider = new BluetoothItemProvider(this,       BluetoothPlugin.getInstance(this).getAvailableDevices());   //设置提供程序   availableDevicesContainer.setItemProvider(availableDevicesItemProvider);   //2.获取已配对的蓝牙设备   ListContainer pairedDevicesContainer = (ListContainer) findComponentById(ResourceTable.Id_list_paired_devices);   pairedDevicesItemProvider = new BluetoothItemProvider(this,       BluetoothPlugin.getInstance(this).getPairedDevices());   //设置提供程序   pairedDevicesContainer.setItemProvider(pairedDevicesItemProvider); } /** * 更新蓝牙状态开关和文本 * @param bluetoothStatus */ private void updateBluetoothStatus(int bluetoothStatus) {    LogUtil.info("MainAbilitySlice", "updateBluetoothStatus:" + bluetoothStatus);   //开关   bluetoothSwitch.setChecked(isBluetoothEnabled());   //状态文本   textBluetoothStatus.setText(getBluetoothStatusString(bluetoothStatus)); } /** * 显示环形进度条 * 用定时器实现了一个进度条,遗憾的是有一定的卡顿 * @param isShow */ private void showProgressBar(boolean isShow) {    LogUtil.info("MainAbilitySlice", "isShow:" + isShow);   LogUtil.info("MainAbilitySlice", "timer=" + timer);   if(isShow){        //显示进度条       progressBar.setVisibility(Component.VISIBLE);       if(timer==null){            timer = new Timer();       }       if(timerTask==null){            timerTask= new TimerTask() {                @Override               public void run() {                    if(percent==10){                        percent=1;                       progressBar.setProgressValue(0);                   }else{                        percent++;                   }                   LogUtil.info("MainAbilitySlice", "percent:" + percent);                   getContext().getUITaskDispatcher().asyncDispatch(new Runnable() {                        @Override                       public void run() {                            progressBar.setProgressValue(percent*10);                       }                   });               }           };           //           timer.schedule(timerTask, 0, 1000);       }   }else {        //隐藏进度条       progressBar.setProgressValue(0);       progressBar.setVisibility(Component.HIDE);       if(timer!=null){            LogUtil.info("MainAbilitySlice", "timer set null");           timer.cancel();           timerTask.cancel();           timer=null;           timerTask=null;       }   } } /** * 获取蓝牙状态 * @return */ private boolean isBluetoothEnabled() {    int status = BluetoothPlugin.getInstance(this).getBluetoothStatus();   LogUtil.info("isBluetoothEnabled", "isBluetoothEnabled:"+status);   return status == BluetoothHost.STATE_ON; } private String getBluetoothStatusString(int bluetoothStatus) {    LogUtil.info("bluetoothStatus", "bluetoothStatus:"+bluetoothStatus);   switch (bluetoothStatus) {        case BluetoothHost.STATE_OFF:       case BluetoothHost.STATE_BLE_TURNING_OFF:           //disabled 不可用           return Constants.BT_DISABLED;       case BluetoothHost.STATE_TURNING_ON:           //turning on 开启           return Constants.BT_TURNING_ON;       case BluetoothHost.STATE_ON:           //enabled 可用的           return Constants.BT_ENABLED;       case BluetoothHost.STATE_TURNING_OFF:           //turning off 关闭           return Constants.BT_TURNING_OFF;       default:           //undefined 未定义           return Constants.BT_UNDEFINED;   } } 

c.实现BluetoothEventListener接口相关函数

@Override public void updateAvailableDevices(List<BluetoothDevice> list) {    //implements BluetoothEventListener   //更新容器数据   availableDevicesItemProvider.updateDeviceList(list); } @Override public void updatePairedDevices(List<BluetoothDevice> list) {    //implements BluetoothEventListener   //更新容器数据   pairedDevicesItemProvider.updateDeviceList(list); } @Override public void notifyBluetoothStatusChanged(int bluetoothStatus) {    LogUtil.info("notifyBluetoothStatusChanged", "bluetoothStatus:"+bluetoothStatus);   //蓝牙状态改变事件通知   updateBluetoothStatus(bluetoothStatus); } @Override public void notifyDiscoveryState(boolean isStarted) {    //蓝牙发现状态的事件通知   showProgressBar(isStarted); } 

d.实现CheckedStateChangedListener接口相关函数

@Override public void onCheckedChanged(AbsButton absButton, boolean isChecked) {    //开关状态改变事件触发   if (absButton.getId() == ResourceTable.Id_bt_switch && containerLists != null) {        if (isChecked) {            LogUtil.info("onCheckedChanged", "enableBluetooth");           //开启蓝牙           BluetoothPlugin.getInstance(this).enableBluetooth();           containerLists.setVisibility(Component.VISIBLE);       } else {            //关闭蓝牙           BluetoothPlugin.getInstance(this).disableBluetooth();           containerLists.setVisibility(Component.HIDE);       }   } } 

e.实现ClickedListener接口相关函数,开始发现蓝牙

@Override public void onClick(Component component) {    LogUtil.info("MainAbilitySlice", "startBtScan...");   //开始发现  扫描蓝牙设备   if (component.getId() == ResourceTable.Id_btn_start_discovery) {        LogUtil.info("MainAbilitySlice", "startBtScan...");       BluetoothPlugin.getInstance(this).startBtScan();   } } 

5.完整代码

附件直接下载

想了解更多内容,请访问:

和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

热门排行
copyright © 2025 powered by 益强资讯全景  滇ICP备2023006006号-31sitemap