任务目标

请根据5月21日课程视频在类微信程序的第一子项中完成“蓝牙聊天功能”。

实验截图

因为设备原因,无法进行两个蓝牙设备的连接通信,故没有运行截图。

初始化界面:

连接蓝牙请求

因为设备限制,无法使用两个蓝牙设备进行测试,对单机发送消息如下结果:

发送消息

部分代码

布局代码

tab01页面的布局:使用约束布局 ConstraintLayout,将button按钮的文字替换成图片

中间的List部分用于显示蓝牙连接的列表

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.fragmentapplication.MainActivity">

<ListView
android:id="@+id/list_conversation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/re_layout">
</ListView>

<RelativeLayout
android:id="@+id/re_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent">

<EditText
android:id="@+id/edit_text_out"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/edit_hint"
android:inputType="text" />

<Button
android:id="@+id/button_send"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:background="@mipmap/enter_48px" />
</RelativeLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

重点代码——通信过程

​ 蓝牙在通信时约定某个范围内的某一频率,双方通过在这一频率上通信来保证通信过程的稳定性。所以蓝牙在扫描通信设备和连接通信设备时会花费较长时间,而当两方建立起通信后,速度会提高。

​ 在注册service时会使用一个标准化128位格式的UUID,这个数值可以通过网络上的UUID生成器随机生成一个,它会对应用的蓝牙服务做唯一标识。

注意:如果使用Android5.0以下的手机,只支持16位UUID,如果过滤UUID填写128位的话,将会搜索不到设备。

通过sendMessage发送消息

private void sendMessage(String message){
if(mChatService.getState() != ChatService.STATE_CONNECTED){
Toast.makeText(this,R.string.not_connected,Toast.LENGTH_SHORT).show();
return;
}

if(message.length() > 0){
byte[] send=message.getBytes();
mChatService.write(send);

mOutStringBuffer.setLength(0);
mOutEditText.setText(mOutStringBuffer);
}
}

通过handleMessage来接受消息

private final Handler mHandler=new Handler(){
@Override
public void handleMessage(Message msg){
switch (msg.what){
case MESSAGE_STATE_CHANGE:
switch (msg.arg1){
case ChatService.STATE_CONNECTED:
mConversationArrayAdapter.clear();
break;
case ChatService.STATE_CONNECTING:
break;
case ChatService.STATE_LISTEN:
case ChatService.STATE_NONE:
break;
}break;
case MESSAGE_WRITE:
byte[]writeBuf =(byte[])msg.obj;
String writeMessage=new String(writeBuf);
mConversationArrayAdapter.add("我: " + writeMessage);
break;
case MESSAGE_READ:
byte[]readBuf =(byte[])msg.obj;
String readMessage=new String(readBuf,0,msg.arg1);
mConversationArrayAdapter.add(mConnectedDeviceName+": "
+readMessage);
break;
case MESSAGE_DEVICE_NAME:
mConnectedDeviceName=msg.getData().getString(DEVICE_NAME);
Toast.makeText(getApplicationContext(),
"链接到"+mConnectedDeviceName,Toast.LENGTH_SHORT)
.show();
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(),
msg.getData().getString(TOAST),Toast.LENGTH_SHORT)
.show();
break;
}
}
};

还有一点想说

​ 写到这里安卓移动开发的课程也接近尾声了,一个学期的学习时间确实像流水一般,感觉什么都还没学到就已经结束了。话说这是第二次用自己的博客完成作业的提交,总想着多写点什么。从一开始跟着老师上课的视频敲代码,到后来反复看回放完成代码的编写,学习的东西越多,安卓开发的交互越多,理解起来就越难。虽然老师并没有给太多难度的知识点,但从零开始学习一门开发语音就足够喝一壶了,即便它的每一部分都那么熟悉——java,xml,控件……

​ 安卓开发的乐趣却也是存在着的,仍然记得使用Android Studio启动第一个程序时出现的虚拟手机的新奇感,页面跳转成功后翻来覆去跳转的喜悦感,着实成为开始学习的一大动力。在进行安卓学习的过程中,老师也布置了很多其他的任务,包括现在用博客的形式提交作业,虽然前几次的作业都是用压缩包提交,但在老师发公告大发雷霆后(非常抱歉)开始正式完成博客(虽然之前有做过博客但没有成功)和github的使用,下定决心完成博客主题的编写后花了两天时间达到现在这种程度,即便还有些小bug,但使得编写博客变成了一件很简单的事情,关于这一点要感谢老师和帮助我的同学,不拘泥于一门课程的学习太棒了!

​ 最后,用自己博客的一句话勉励下:眼要看远,脚要迈近,加油。

最后的最后,没有好看的封面啊,,,

项目原始代码

请戳这里α->Lkuf