蓝牙聊天App设计3:Android Studio制作蓝牙聊天通讯软件(完结,蓝牙连接聊天,结合生活情景进行蓝牙通信的通俗讲解,以及代码功能实现,内容详细,讲解通俗易懂)

这篇具有很好参考价值的文章主要介绍了蓝牙聊天App设计3:Android Studio制作蓝牙聊天通讯软件(完结,蓝牙连接聊天,结合生活情景进行蓝牙通信的通俗讲解,以及代码功能实现,内容详细,讲解通俗易懂)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:蓝牙聊天App设计全部有三篇文章(一、UI界面设计,二、蓝牙搜索配对连接实现,三、蓝牙连接聊天),这篇文章是:三、蓝牙连接聊天。

课程1:Android Studio小白安装教程,以及第一个Android项目案例“Hello World”的调试运行
课程2:蓝牙聊天App设计1:Android Studio制作蓝牙聊天通讯软件(UI界面设计)
课程3:蓝牙聊天App设计2:Android Studio制作蓝牙聊天通讯软件(蓝牙搜索配对连接)
课程4:蓝牙聊天App设计3:Android Studio制作蓝牙聊天通讯软件(完结,蓝牙连接聊天,结合生活情景进行蓝牙通信的通俗讲解,以及代码功能实现,内容详细,讲解通俗易懂)

本次任务:
本次项目的任务是制作一个基于蓝牙通信协议的蓝牙聊天软件。具体内容就是用户双方在手机上安装本软件后,通过蓝牙连接后进行“微信聊天”。文章末尾附项目下载链接共享。

效果图与视频:

用户1效果图
android studio实现聊天,android studio,生活,android,java,wechat
用户2效果图
android studio实现聊天,android studio,生活,android,java,wechat
效果视频

基于Android的蓝牙通信聊天软件(效果视频)

文章说明:
本文将结合生活情景,讲解蓝牙通信原理。具体讲解代码实现过程并详细解析代码含义。本文的前提是你已经能够掌握蓝牙的搜索展示,连接配对功能,如果还未掌握,建议先观看前面文章,一步一个脚印来。

在明确任务和目标效果后,下面开始本项目的内容讲解:

android studio实现聊天,android studio,生活,android,java,wechat
上图是蓝牙通信的原理图,建议看完,清楚整个功能流程后,再针对每个环节进行开发。为了进一步加深理解,下面举一个情景例子。

周末,你在家里一个人呆着无聊,就通过发朋友圈(开启BluetoothServerSocket)的方式,邀请一位朋友来家里做客(由于你家太小,只能待两个人)。你的朋友老王看到你的朋友圈(BluetoothServerSocket)后,立刻就私信你,询问自己能否去你家里做客聊天(发起访问通道请求)。你答应了,给了老王你家(BluetoothSocket)的详细地址,并立刻删除刚才的朋友圈(关闭BluetoothServerSocket),防止其他朋友看到后也要来做客。接下来,你就一直待在家里,等待老王上门(Accept)。老王到了你家门口后,就一直按门铃(connect),直到你开门邀请进去。到了这个时候,其实你们就已经处在同个聊天场所(BluetoothSocket)了。坐下聊天过程中,你和老王轮流说话(write),但是无论你们是否在说话,耳朵却一直保持倾听(read)的状态。到了中午时,由于老王下午还有事要处理,便与你告别,离开你家(断开BluetoothSocket)。老王离开后,你就重新发了朋友圈(开启BluetoothServerSocket),等待下一位朋友的私信做客。

概念的提前解释

下面的内容是编程过程中会出现的常见词,在这里先提前通俗解析一下,起码得在心中有个概念,这是干什么用的,有什么区别?

1.Socket(套接字)
用于进程间的通信,创建一个Socket,其实就是相当于创建一个聊天通道(BluetoothServerSocket和BluetoothSocket),也就是聊天场所的建立。

2.Handler
用于线程间的通信。与前面的Binder/Socket用于进程间通信不同,Handler用于同进程的线程间通信。用最简单的话描述: handler其实就是子线程运行并生成Message后,Looper获取message并传递给Handler。本质是“消息池”、“快递中转站”,实现不同线程间的信息交互。
例如:在聊天场景中,将聊天线程中需更新UI的操作信息传递到UI主线程,从而实现聊天线程对UI的更新处理,最终实现异步消息的处理
android studio实现聊天,android studio,生活,android,java,wechat

3.Handler中obtainMessage与new Message的区别:
(1)obtainmessage() 相当于向快递中转站(Handler)拿一个空的旧盒子(Message),不需要另开辟空间,obtianmessage指循环利用旧盒子
(2)new Message() 相当于向快递中转站(Handler)拿一个空的新盒子(Message),需要重新申请,效率低

4.Message
message其实相当于一个快递盒子,是线程间的传递媒介。聊天子线程把需要更新的文字信息包装在message这个盒子里,然后把message盒子送到Handler这个“物流中心”,Handler又把需要更新的内容准确传递到主线程手里,然后更新UI。message的结构主要包括what字段和obj字段,what用来标明信息类型(int型),obj用来寄放信息内容(String型),例如:MSG_GOT_DATA代表告诉Handler,我已经正常收到了信息,信息的内容是“我想问一下你现在吃饭没?”,Message的结构如下所示:

what obj
MSG_GOT_DATA 我想问一下你现在吃饭没?

5.sendMessage和sendEmptyMessage的区别
二者的作用都是线程向Handler发送信息message(也就是寄快递)
(1)sendEmptyMessage(int what) 与sendMessage(Message msg) 相比,只有盒子的what空间能使用,性能上比sendMessage快,但局限性很明显
(2)sendMessage(Message msg) 相当于向快递中转站(Handler)寄一整个盒子,其中盒子的what空间和obj空间都能使用

what内容的获取 obj内容的获取
int what = message.what String obj = message.obj
what = MSG_GOT_DATA obj = “我想问一下你现在吃饭没?”

Constant.java是用来预先定义一些下面可能需要用到的常量(其实就是对sendEmptyMessage(int what)中“what”内容的规定)

package com.example.wyb.btw3.connect;
/**
 * Created by WYB on 2023/4/24.
 */
public class Constant {
    public static final String CONNECTTION_UUID = "00001101-0000-1000-8000-00805F9B34FB";
    /**
     * 开始监听
     */
    public static final int MSG_START_LISTENING = 1;

    /**
     * 结束监听
     */
    public static final int MSG_FINISH_LISTENING = 2;
    /**
     * 有客户端连接
     */
    public static final int MSG_GOT_A_CLINET = 3;

    /**
     * 连接到服务器
     */
    public static final int MSG_CONNECTED_TO_SERVER = 4;
    /**
     * 获取到数据
     */
    public static final int MSG_GOT_DATA = 5;
    /**
     * 出错
     */
    public static final int MSG_ERROR = -1;
}

//明确快递中转站(Handler)收到what类型后,向UI界面传递什么更新内容
private class MyHandler extends Handler {
    public void handleMessage(Message message) {
        super.handleMessage(message);
        switch (message.what) {
            case Constant.MSG_GOT_DATA:		//这些代表什么,文章前面的定义有说明
                showToast("data:" + String.valueOf(message.obj));
                break;
            case Constant.MSG_ERROR:
                showToast("error:" + String.valueOf(message.obj));
                Log.e("提示","error:" + String.valueOf(message.obj));
                break;
            case Constant.MSG_CONNECTED_TO_SERVER:
                showToast("连接到服务端");
                break;
           case Constant.MSG_GOT_A_CLINET:
                showToast("找到客户端");
                break;
        }
    }
}

功能实现

一、创建请求访问通道并开启端口监听(服务端):

请求访问通道的建立:需要通过创建一个AcceptThread线程来实现。之所以需要创建线程,是因为Accept()会处于阻塞状态,一直监听,等待连接请求。所以需要创建一个线程来专门干这事。

mAcceptThread = new AcceptThread(mblueToothController.getAdapter(),mUIHandler);
mAcceptThread.start();

AcceptThread.java的完整代码如下(每段代码都有详细功能解析)

package com.example.wyb.btw3.connect;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import java.io.IOException;
import java.util.UUID;
/**
 * Created by WYB on 2023/4/24.
 */
public class AcceptThread extends Thread {
    private static final String NAME = "BlueToothClass";
    private static final UUID MY_UUID = UUID.fromString(Constant.CONNECTTION_UUID);
    private final BluetoothServerSocket mmServerSocket;
    private final BluetoothAdapter mBluetoothAdapter;
    private final Handler mHandler;
    private ConnectedThread mConnectedThread;
    public AcceptThread(BluetoothAdapter adapter, Handler handler) {
        mBluetoothAdapter = adapter;
        mHandler = handler;
        BluetoothServerSocket tmp = null;
        try {
            // MY_UUID是应用程序的UUID,客户端代码使用相同的UUID,服务端开启端口并返回一个BluetoothServerSocket,等待客户端请求
            tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
        } catch (IOException e) { }
        mmServerSocket = tmp;
    }
    //run函数是线程执行start()后执行的函数
    public void run() {
        BluetoothSocket socket;
        //持续监听,直到出现异常或返回socket
        while (true) {
            try {
                mHandler.sendEmptyMessage(Constant.MSG_START_LISTENING);
                socket = mmServerSocket.accept();//accept处于阻塞状态,直到收到客户端请求,并返回给客户端一个BluetoothSocket对象,也就是聊天通道的建立
            } catch (IOException e) {
                mHandler.sendMessage(mHandler.obtainMessage(Constant.MSG_ERROR, e));
                break;
            }
            // 如果一个连接被接受
            if (socket != null) {
                // 在单独的线程中完成管理连接的工作
                manageConnectedSocket(socket);
                try {
                    mmServerSocket.close();
                    mHandler.sendEmptyMessage(Constant.MSG_FINISH_LISTENING);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }
    private void manageConnectedSocket(BluetoothSocket socket) {
        //只支持同时处理一个连接,因为多个连接的话涉及内容复杂,所以本项目只接受一个设备连接。如果已经存在一个在运行的聊天线程,则关闭掉
        if( mConnectedThread != null) {
            mConnectedThread.cancel();
        }
        mHandler.sendEmptyMessage(Constant.MSG_GOT_A_CLINET);
        //创建一个聊天线程(ConnectedThread,具体实现文章后面会详细解读)
        mConnectedThread = new ConnectedThread(socket, mHandler);
        mConnectedThread.start();
    }
    /**
     * 取消监听socket,使此线程关闭
     */
    public void cancel() {
        try {
            mmServerSocket.close();
            mHandler.sendEmptyMessage(Constant.MSG_FINISH_LISTENING);
        } catch (IOException e) { }
    }
    //发送信息的实现
    public void sendData(byte[] data) {
        if( mConnectedThread!=null){
            mConnectedThread.write(data);
        }
    }
}

二、发起聊天请求并建立通信通道(客户端):

device指服务端的蓝牙设备,mblueToothController.getAdapter()指本客户端的蓝牙适配器。创建线程是因为connect()这个函数会发生阻塞。

mConnectThread = new ConnectThread(device,mblueToothController.getAdapter(),mUIHandler);
mConnectThread.start();

ConnectThread.java的完整代码如下(每段代码都有详细功能解析)

package com.example.wyb.btw3.connect;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
/**
 * Created by WYB on 2023/4/24.
 */
public class ConnectThread extends Thread {
    private static final UUID MY_UUID = UUID.fromString(Constant.CONNECTTION_UUID);
    private final BluetoothSocket mmSocket;
    private final BluetoothDevice mmDevice;
    private BluetoothAdapter mBluetoothAdapter;
    private final Handler mHandler;
    private ConnectedThread mConnectedThread;
    public ConnectThread(BluetoothDevice device, BluetoothAdapter adapter, Handler handler) {
        BluetoothSocket tmp = null;
        mmDevice = device;
        mBluetoothAdapter = adapter;
        mHandler = handler;
        // 用BluetoothSocket连接到给定的蓝牙设备
        try {
            //通过同一个UUID向服务端device发起连接请求,服务端接收请求后会建立并返回一个BluetoothSocket聊天通道
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) { }
        mmSocket = tmp;
    }
    //由于请求过程处于阻塞状态,所以整个请求过程得用线程
    public void run() {
        // 关闭蓝牙的搜索功能,避免请求过程出现数据错误
        mBluetoothAdapter.cancelDiscovery();
        try {
            // 通过BluetoothSocket通道发起设备连接请求,阻塞运行直到成功或抛出异常
            mmSocket.connect();
        } catch (Exception connectException) {
            mHandler.sendMessage(mHandler.obtainMessage(Constant.MSG_ERROR, connectException));
            // 如果无法连接则关闭socket并退出
            try {
                mmSocket.close();
            } catch (IOException closeException) { }
            return;
        }
        // 在单独的线程中完成管理连接的工作
        manageConnectedSocket(mmSocket);
    }
    //开门成功后就开始下一个任务
    private void manageConnectedSocket(BluetoothSocket mmSocket) {
        //发送连接成功提示文字
        mHandler.sendEmptyMessage(Constant.MSG_CONNECTED_TO_SERVER);
        //创建连接后的处理线程,即通信线程
        mConnectedThread = new ConnectedThread(mmSocket, mHandler);
        mConnectedThread.start();
    }
    /**
     * 取消正在进行的连接并关闭socket
     */
    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) { }
    }
    /**
     * 发送数据
     */
    public void sendData(byte[] data) {
        if( mConnectedThread!=null){
            mConnectedThread.write(data);
        }
    }
}

三、数据交互与断开(服务端与客户端的聊天实现)

数据交互阶段的原理其实特别简单,就是服务端和客户端都分别开启一个聊天线程,聊天线程的主要功能其实就一个——一直执行read()。也就是处于监听状态,等待另一方write()。

ConnectedThread.java的完整代码如下(每段代码都有详细功能解析)

package com.example.wyb.btw3.connect;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
 * Created by WYB on 2023/4/24.
 */
public class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;
    private final Handler mHandler;
    public ConnectedThread(BluetoothSocket socket, Handler handler) {
        mmSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;
        mHandler = handler;
        try {
            tmpIn = socket.getInputStream();	//输入流
            tmpOut = socket.getOutputStream();	//输出流
        } catch (IOException e) { }
        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }
    public void run() {
        byte[] buffer = new byte[1024];  // 用于流的缓冲存储
        int bytes; // 从read()返回bytes
        // 持续监听InputStream(也就是对方发来的信息),直到出现异常
        while (true) {
            try {
                // 从InputStream读取数据,也就是我前面提到的一直保持read()
                bytes = mmInStream.read(buffer);
                // 将获得的bytes发送到UI层activity
                if( bytes >0) {
                	//obtainMessage可以看前面的解析
                    Message message = mHandler.obtainMessage(Constant.MSG_GOT_DATA, new String(buffer, 0, bytes, "utf-8"));
                    mHandler.sendMessage(message);
                }
                Log.d("GOTMSG", "message size" + bytes);
            } catch (IOException e) {
                mHandler.sendMessage(mHandler.obtainMessage(Constant.MSG_ERROR, e));
                break;
            }
        }
    }
    /**
     * 在main中调用此函数,将数据发送到远端设备中
     */
    public void write(byte[] bytes) {
        try {
            mmOutStream.write(bytes);
        } catch (IOException e) { }
    }
    /**
     * 在main中调用此函数,断开连接
     */
    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) { }
    }
}

四、bluetoothChat项目功能demo分享:
链接:https://pan.baidu.com/s/1z8tW3aA7a5knKxiwlE3BFw 提取码:3d53

五、bluetoothChat最终App分享:
链接:https://pan.baidu.com/s/1XOpO62n8e2SfdyJzWf5Mwg 提取码:12pf文章来源地址https://www.toymoban.com/news/detail-528241.html

到了这里,关于蓝牙聊天App设计3:Android Studio制作蓝牙聊天通讯软件(完结,蓝牙连接聊天,结合生活情景进行蓝牙通信的通俗讲解,以及代码功能实现,内容详细,讲解通俗易懂)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于android的即时通讯APP 聊天APP

    该项目是基于Android 的聊天APP系统,该APP包含前台,后台管理系统,前台包含用户通讯录,用户详情,用户聊天服务,用户二维码,发现功能,发现详情 , 个人中心, 个人信息, 编辑信息,上传头像,注册,登录,退出 等操作 。后台包含 系统管理,用户管理,聊天内容管理,聊天

    2024年02月02日
    浏览(51)
  • Android Studio 简易通讯录制作 (Java)

    通讯录首页:  添加联系人页面:  修改联系人: 删除联系人:  程序代码: MainActivity.java MyAdapter.java  DBHelper.java User.java  activity_main.xml dialog.xml  item.xml colors.xml  详细见:https://gitee.com/love1213/Android-Studio-Contacts.git

    2024年02月11日
    浏览(44)
  • Android Studio 制作微信,登入界面,输入密码界面,跳转手机登录界面,以及聊天界面

    2.打开Android Studio。 3.选择 \\\"Create New Project\\\"。 4.在 \\\"Create New Project\\\" 对话框中,输入项目名称、选择存储位置等信息。 5.选择最低支持的Android版本,并选择一个适合的活动模板(例如,Empty Activity)。 6.点击 \\\"Finish\\\" 创建新的Android项目。 8.打开 \\\"activity_main.xml\\\" 文件,该文件用于定

    2024年02月07日
    浏览(44)
  • Android Studio制作一个简单的计算器APP

    虽然现在我们日常生活中很少用到计算器,但是第一次尝试在Android Studio上做一个计算器 程序设计步骤: (1)在布局文件中声明编辑文件框EditText,按钮Button等组件。 (2)在MainActivity中获取组件实例。 (3)通过swtich函数,判断输入的内容,并进行相应操作,通过getText()获

    2024年02月11日
    浏览(49)
  • 使用Android studio完成简易智能家居APP的制作(含源码工程包)

     (填下坑,把我之前答应大家的完整软件代码翻出来,供大家一起学习) 可以看看实现效果先:   智能家居APP展示视频(含源码)_哔哩哔哩_bilibili 目录 项目说明 功能介绍 系统功能需求 具体实现的软件功能  1、地图定位 2、蓝牙按钮 3、远端控制  核心代码展示说明 蓝牙

    2024年02月06日
    浏览(47)
  • 使用Android Studio 利用极光推送SDK 制作手机 APP 实现远程测试技术 (第一部)

    总参考文章:https://blog.csdn.net/qq_38436214/article/details/105073213 Android Studio 安装配置教程 - Windows(详细版) 1.JDK 安装与环境变量配置(Win10详细版) 《jdk-8u371-windows-i586.exe》 https://blog.csdn.net/qq_38436214/article/details/105071088 此时会让登录账号密码: https://login.oracle.com/mysso/signon.jsp 账号:

    2024年02月03日
    浏览(49)
  • 基于Android平台的记事本软件(Android Studio项目+报告+app文件)

    移动应用开发技术 期末考核报告 题    目:         基于 Android 平台的记事本软件              学生姓名                               学生学号                               专      业                            班     级

    2024年02月08日
    浏览(48)
  • Android studio 简单登录APP设计

    一、登录界面: 二、xml布局设计:

    2024年01月17日
    浏览(54)
  • 即时聊天app开发-即时通讯app开发方案分析

    如今,即时聊天APP层出不穷,它已经成为人们日常生活中密不可分的社交工具。如今,即时聊天APP不仅是聊天工具,也是企业营销的利器。我们经常可以在聊天主页上看到一些广告。如有必要,用户可以直接点击广告了解详情。即时聊天APP作为未来跨越互联网和移动互联网的

    2024年02月05日
    浏览(45)
  • 51与JDY31蓝牙模块通讯,51驱动JDY31蓝牙APP点灯

    本次实验用到是JDY31蓝牙模块,JDY-31 蓝牙基于蓝牙 3.0 SPP 设计, 点击图片购买 蓝牙模块是串口通讯,单片机也有串口通讯,我们只需要配置好既可以实现单片机于蓝牙通讯,甚至是实现更多的功能,本文对刚学习51需要制作蓝牙小车的帮助很大 STC89C52的UART有四种工作模式:

    2023年04月12日
    浏览(77)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包