蓝牙聊天 第3节 获取要连接的设备

第3节 获取要连接的设备

这一节我们开始设计蓝牙聊天应用的界面。根据之前的规划,连接管理将放在单独的ConnectionManager模块当中,所以每当要使用连接功能的时候,我们就暂时把它空着,等到ConnectionManager开发完成之后再加进来。

这里我们将完成下面的界面设计,

3.1 主界面

主界面是一个独立的ActivityChatActivity,它要实现三个主要功能,

  1. 当蓝牙没有开启或者设备不能被发现的时候,请求用户打开对应的功能;
  2. 下方有输入框输入要发送的文字内容,点击按钮后能实现文字的发送;输入框上方的大部分区域用来显示聊天的内容;
  3. 菜单栏根据当前蓝牙连接的状态,显示不同的菜单项。例如,没有连接时启动蓝牙设备选择界面;

3.1.1 打开蓝牙功能

ChatActivity创建的时候,查询当前蓝牙设备是否满足运行的要求,

  1. 提示开启蓝牙功能,

  2. 提示开启被其它蓝牙设备发现的功能,

3.1.2 界面布局

界面布局比较简单,使用垂直的线性布局LinearLayout将界面分成两个区域,上面的大区域显示聊天的内容,用ListView的显示;下面文字输入和发送用TextEditorImageButton组合起来。

在代码中,获取将来要操作的控件,

3.1.3 菜单项显示

菜单栏根据当前蓝牙连接的状态,显示不同的菜单项,

  1. 没有连接时,显示启动连接。点击该菜单,将启动显示可连接设备的ActivityDeviceListActivity

  2. 正在连接时,显示取消。点击该菜单,将取消正在进行的连接;

  3. 已经连接时,显示断开连接。点击该菜单,将断开与其它设备已经建立好的连接;

由于这里要根据蓝牙设备连接的状况设计不同的逻辑,所以接下来设计的ConnectionManager要为其它模块提供获取当前连接状态的接口。

目前,我们就暂时将它设计成满足条件1的状况,

  1. 定义一个菜单main_menu.xml

  2. 将菜单添加到菜单栏中,

  3. 响应菜单栏,启动DeviceListActivity获取可以连接到设备名称

    我们从ChatActivity启动DeviceListActivity,目的是要获取DeviceListActivity返回的内容-蓝牙设备的连接地址。所以不能简单的使用startActivity()方法了。

    1. 两个Activity之间传递数据,可以使用startActivityForResult()方法,这里面要设置一个ResultCode,用来主返回结果的时候使用辨别结果对应的是哪个请求,

    2. 返回的结果将在onActivityResult()函数中被通知到。这里参数的requestCode就是我们在startActivityForResult()中填入的那个数值;而resultCode代表另一个Activity是否如我们所愿返回了结果,

      得到蓝牙设备的地址后,就可以通过ConnectionManager模块去连接设备了。

在蓝牙设备连接之前,是不需要编辑文字和发送内容的。所以,可以使用ViewsetEnabled()函数,将TextEditorImageButton给禁用掉(点击它们不会有任何响应)。等到设备连接上之后,在把它们开启。

3.2 设备列表界面开发

为设备列表界面创建一个DeviceListActivity

3.2.1 主界面布局

  1. 界面布局很简单,就是一个ListView

    在代码中,设置上返回按钮,并获取这个ListView,以备将来使用,

  2. 为了展示可连接的蓝牙设备,我们会把收集到的可连接设备保存起来,通过ListView进行显示。

    这里将自定义一个AdapterDeviceItemAdapter,让它显示设备的名字和地址,

    1. 数据项的界面布局,

    2. 自定义的DeviceItemAdapter将继承自ArrayAdapter

    3. 使用ListView

3.2.2 展现可连接的设备

可连接的设备包括两种,

  1. 曾经连接过的,已经被系统记录在案,连接这种设备时,系统不会提示用户有设备需要配对;
  2. 完全新发现的设备,连接这种设备时,系统会提示用户有设备需要配对。

3.2.2.1 获取已绑定过的设备

获取第一种设备很简单,使用BluetoothAdaptergetBondedDevices()方法就可以了。找到后,添加到ListView中显示,

3.2.2.2 获取新发现的设备

获取第二种设备,就采用技术验证时使用的mBluetoothAdapter.startDiscovery()方法;

  1. 首先要注册一个BroadcastReceiver,然后startDiscovery(),之后系统会发出BluetoothAdapter.ACTION_DISCOVERY_STARTED的广播,告知搜索开始;发出BluetoothAdapter.ACTION_DISCOVERY_FINISHED的广播,告知搜索结束,

  2. 根据收到的广播,更新显示列表。假如搜索到的设备是曾经绑定过的,说明之前已经加到设备列表里面了,这里不需要重复添加,

    注意,这里能够在BroadcastReceiveronReceive()方法中直接修改界面元素,是因为onReceive()是运行在UI线程-主线程当中的。

  3. DeviceListActivity销毁的时候,注销BroadcastReceiver,同时也别忘了取消可能正在进行的搜索,

至此,DeviceListActivity已经可以列出可被发现和连接到设备了。

3.2.3 设置菜单栏

设置菜单栏的菜单项device_menu.xml,让菜单项一直显示,

我们将根据搜索设备的状态更改该菜单项的名称。所以,这里要定义当前搜索的状态,

  1. 当正在搜索的时候,显示取消,此时状态是BT_SEARCH_STATE_SEARCHING
  2. 当没有搜索的时候,显示搜索,此时对应的状态是BT_SEARCH_STATE_IDLE

这两种状态,都要记录下来,

在代码中添加菜单项,

响应菜单项,

为了更新菜单项,还需要BroadcastReceiver的配合,

3.3 得到要连接的设备

当用户点击要连接的设备后,将把该设备的地址返回给ChatActivity,由ChatActivity去连接设备。

  1. 为设备列表设置点击响应;
  2. 假如点击的时候还在进行搜索,取消搜索;
  3. 获取设备的地址,将它存储到Intent当中,最后通过setResult()方法,将结果传递给启动DeviceListActivityActivityChatActivity

点击之后,选中的设备地址会传递到ChatActivityonActivityResult()方法中,


***************************************

本系列课程使用到的Arduino开发板、扩展板以及其他相关的传感器,各位可以根据我们文章中介绍的硬件在淘宝网选购。
您也可以在我们的网店跟我学Arduino编程中购买,这些相关硬件都由我们为您把关购买,为大家节省选择的精力与时间。同时也感谢大家对我们这些码农的支持。

最后再次感谢各位读者对安豆的支持,谢谢:)


QQ交流群

571747694