目录

  • 添加蓝牙权限
  • 在文件res/values/strings.xml里,添加程序运行过程中的状态描述文本
  • 编写布局文件添加一个
  • 编写用于蓝牙会话的服务组件ChatService
  • 建立供BluetoothChat使用的菜单文件optionmenu.xml
  • 新建组件DeviceList,实现选取与之会话的蓝牙设备
  • 使用菜单File→Refactor→Rename,重命名模块的MainActivity为BluetoothChat
  • 附加device_name和message两个xml文件
  • 实验代码

添加蓝牙权限

 <!--下面2个是普通权限,只需要在清单文件里注册,不需要在程序里动态申请--><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /><uses-permission android:name="android.permission.BLUETOOTH" />

在文件res/values/strings.xml里,添加程序运行过程中的状态描述文本

<?xml version="1.0" encoding="utf-8"?>
<resources><string name="app_name">蓝牙Demo</string><string name="send">发送</string><string name="not_connected">你没有链接一个设备</string><string name="bt_not_enabled_leaving">蓝牙不可用,离开聊天室</string><string name="title_connecting">链接中...</string><string name="title_connected_to">连接到:</string><string name="title_not_connected">无链接</string><string name="scanning">蓝牙设备搜索中...</string><string name="select_device">选择一个好友链接</string><string name="none_paired">没有配对好友</string><string name="none_found">附近没有发现好友</string><string name="title_paired_devices">已配对好友</string><string name="title_other_devices">其它可连接好友</string><string name="button_scan">搜索好友</string><string name="connect">我的好友</string><string name="discoverable">设置在线</string><string name="back">退出</string><string name="startVideo">开始聊天</string><string name="stopVideo">结束聊天</string>
</resources>

编写布局文件添加一个

使用垂直线性布局并嵌套水平线性布局实现,添加,添加1个Toolbar控件,其内包含2个水平的TextView控件;在Toolbar控件的下方添加1个ListView控件,用于显示聊天内容;最后在ListView控件的下方添加水平放置的1个EditText控件和一个Button控件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><!--新版Android支持的Toolbar,对标题栏布局--><androidx.appcompat.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="wrap_content"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"><TextViewandroid:id="@+id/title_left_text"style="?android:attr/windowTitleStyle"android:layout_width="0dp"android:layout_height="match_parent"android:layout_alignParentLeft="true"android:layout_weight="1"android:gravity="left"android:ellipsize="end"android:singleLine="true" /><TextViewandroid:id="@+id/title_right_text"android:layout_width="0dp"android:layout_height="match_parent"android:layout_alignParentRight="true"android:layout_weight="1"android:ellipsize="end"android:gravity="right"android:singleLine="true"android:textColor="#fff" /></LinearLayout></androidx.appcompat.widget.Toolbar><ListView android:id="@+id/in"android:layout_width="match_parent"android:layout_height="match_parent"android:stackFromBottom="true"android:transcriptMode="alwaysScroll"android:layout_weight="1" /><LinearLayoutandroid:orientation="horizontal"android:layout_width="match_parent"android:layout_height="wrap_content" ><EditText android:id="@+id/edit_text_out"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:layout_gravity="bottom" /><Button android:id="@+id/button_send"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/send"/></LinearLayout>
</LinearLayout>

编写用于蓝牙会话的服务组件ChatService

定义了3个内部类:AcceptThread(接受新连接)、ConnectThread(发出连接)和ConnectedThread (已连接)

AcceptThread

 private class AcceptThread extends Thread {private final BluetoothServerSocket mmServerSocket;public AcceptThread() {BluetoothServerSocket tmp = null;try {//使用射频端口(RF comm)监听tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);} catch (IOException e) {}mmServerSocket = tmp;}@Overridepublic void run() {setName("AcceptThread");BluetoothSocket socket = null;while (mState != STATE_CONNECTED) {try {socket = mmServerSocket.accept();} catch (IOException e) {break;}if (socket != null) {synchronized (ChatService.this) {switch (mState) {case STATE_LISTEN:case STATE_CONNECTING:connected(socket, socket.getRemoteDevice());break;case STATE_NONE:case STATE_CONNECTED:try {socket.close();} catch (IOException e) {e.printStackTrace();}break;}}}}}public void cancel() {try {mmServerSocket.close();} catch (IOException e) {e.printStackTrace();}}}

ConnectThread

    private class ConnectThread extends Thread {private final BluetoothSocket mmSocket;private final BluetoothDevice mmDevice;public ConnectThread(BluetoothDevice device) {mmDevice = device;BluetoothSocket tmp = null;try {tmp = device.createRfcommSocketToServiceRecord(MY_UUID);} catch (IOException e) {e.printStackTrace();}mmSocket = tmp;}@Overridepublic void run() {setName("ConnectThread");mAdapter.cancelDiscovery();try {mmSocket.connect();} catch (IOException e) {connectionFailed();try {mmSocket.close();} catch (IOException e2) {e.printStackTrace();}ChatService.this.start();return;}synchronized (ChatService.this) {mConnectThread = null;}connected(mmSocket, mmDevice);}public void cancel() {try {mmSocket.close();} catch (IOException e) {e.printStackTrace();}}}

ConnectedThread

    private class ConnectedThread extends Thread {private final BluetoothSocket mmSocket;private final InputStream mmInStream;private final OutputStream mmOutStream;public ConnectedThread(BluetoothSocket socket) {mmSocket = socket;InputStream tmpIn = null;OutputStream tmpOut = null;try {tmpIn = socket.getInputStream();tmpOut = socket.getOutputStream();} catch (IOException e) {e.printStackTrace();}mmInStream = tmpIn;mmOutStream = tmpOut;}@Overridepublic void run() {byte[] buffer = new byte[1024];int bytes;while (true) {try {bytes = mmInStream.read(buffer);mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer).sendToTarget();} catch (IOException e) {connectionLost();break;}}}public void write(byte[] buffer) {try {mmOutStream.write(buffer);mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();} catch (IOException e) {e.printStackTrace();}}public void cancel() {try {mmSocket.close();} catch (IOException e) {e.printStackTrace();}}}

建立供BluetoothChat使用的菜单文件optionmenu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"><item android:id="@+id/scan"android:icon="@android:drawable/ic_menu_myplaces"android:title="@string/connect" /><item android:id="@+id/discoverable"android:icon="@android:drawable/ic_menu_view"android:title="@string/discoverable" /><item android:id="@+id/back"android:icon="@android:drawable/ic_menu_close_clear_cancel"android:title="@string/back" />
</menu>

新建组件DeviceList,实现选取与之会话的蓝牙设备

本程序供菜单项主界面的选项菜单“我的友好”调用,用于:
(1)显示已配对的好友列表;
(2)搜索可配对的好友进行配对
(3)新选择并配对的蓝牙设备将刷新好友列表
定义已配对和未配对的蓝牙设备列表

        //已配对蓝牙设备列表ListView pairedListView =findViewById(R.id.paired_devices);pairedListView.setAdapter(mPairedDevicesArrayAdapter);pairedListView.setOnItemClickListener(mPaireDeviceClickListener);//未配对蓝牙设备列表ListView newDevicesListView = findViewById(R.id.new_devices);newDevicesListView.setAdapter(mNewDevicesArrayAdapter);newDevicesListView.setOnItemClickListener(mNewDeviceClickListener);

关键技术:动态注册一个广播接收者,处理蓝牙设备扫描的结果

//动态注册广播接收者IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);registerReceiver(mReceiver, filter);filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);registerReceiver(mReceiver, filter);mBtAdapter = BluetoothAdapter.getDefaultAdapter();Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();if (pairedDevices.size() > 0) {findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);for (BluetoothDevice device : pairedDevices) {mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());}} else {String noDevices = getResources().getText(R.string.none_paired).toString();mPairedDevicesArrayAdapter.add(noDevices);}

其中两个监听事件mPaireDeviceClickListener,mNewDeviceClickListener为

private AdapterView.OnItemClickListener mPaireDeviceClickListener = new AdapterView.OnItemClickListener() {public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {mBtAdapter.cancelDiscovery();String info = ((TextView) v).getText().toString();String address = info.substring(info.length() - 17);Intent intent = new Intent();intent.putExtra(EXTRA_DEVICE_ADDRESS, address);  //Mac地址setResult(Activity.RESULT_OK, intent);finish();}};private AdapterView.OnItemClickListener mNewDeviceClickListener = new AdapterView.OnItemClickListener() {public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {mBtAdapter.cancelDiscovery();Toast.makeText(DeviceList.this, "请在蓝牙设置界面手动连接设备", Toast.LENGTH_SHORT).show();Intent intent = new Intent( Settings.ACTION_BLUETOOTH_SETTINGS);startActivityForResult(intent,1);}};

使用菜单File→Refactor→Rename,重命名模块的MainActivity为BluetoothChat

实验步骤:
(1)在两个手机分别安装、运行本应用。如果未打开手机蓝牙,则进入打开蓝牙设置界面;
(2)在OptionMenu(选项菜单)里,选择“我的好友”,即可直接连接,再进行会话;
(3)新建好友前,需要先使用选项菜单“设置在线”,即要求对方可见(能被扫描到)。
然后,单击“搜索好友”按钮。

得到本地蓝牙适配器

  mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();if (mBluetoothAdapter == null) {Toast.makeText(this, "蓝牙不可用", Toast.LENGTH_LONG).show();finish();return;}if (!mBluetoothAdapter.isEnabled()) { //若当前设备蓝牙功能未开启Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(enableIntent, REQUEST_ENABLE_BT); //} else {if (mChatService == null) {setupChat();  //创建会话}}

使用Handler对象在UI主线程与子线程之间传递消息

private final Handler mHandler = new Handler() {   //消息处理@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case MESSAGE_STATE_CHANGE:switch (msg.arg1) {case ChatService.STATE_CONNECTED:mTitle.setText(R.string.title_connected_to);mTitle.append(mConnectedDeviceName);mConversationArrayAdapter.clear();break;case ChatService.STATE_CONNECTING:mTitle.setText(R.string.title_connecting);break;case ChatService.STATE_LISTEN:case ChatService.STATE_NONE:mTitle.setText(R.string.title_not_connected);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;}}};

返回进入好友列表操作后的数回调方法

public void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult( requestCode, resultCode, data );switch (requestCode) {case REQUEST_CONNECT_DEVICE:if (resultCode == Activity.RESULT_OK) {String address = data.getExtras().getString( DeviceList.EXTRA_DEVICE_ADDRESS );BluetoothDevice device = mBluetoothAdapter.getRemoteDevice( address );mChatService.connect( device );} else if (resultCode == Activity.RESULT_CANCELED) {Toast.makeText( this, "未选择任何好友!", Toast.LENGTH_SHORT ).show();}break;case REQUEST_ENABLE_BT:if (resultCode == Activity.RESULT_OK) {setupChat();} else {Toast.makeText( this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT ).show();finish();}}}

附加device_name和message两个xml文件

两个文件只需要添加一个TextView组件即可

<TextView xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="18sp"android:padding="5dp"/>

实验代码

BlueToothChat.

android studio实现蓝牙通信相关推荐

  1. 基于Android Studio的蓝牙通信的简单应用与开发

    实现基于Android Studio的蓝牙通信的简单应用与开发 实现蓝牙通信 界面展示 核心文件 部分代码展示 总结 实现蓝牙通信 通过权限申请与代码实现,完成蓝牙通信的简单应用与开发. 界面展示 核 ...

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

    前言:蓝牙聊天App设计全部有三篇文章(一.UI界面设计,二.蓝牙搜索配对连接实现,三.蓝牙连接聊天),这篇文章是:三.蓝牙连接聊天. 课程1:Android Studio小白安装教程,以及第一个An ...

  3. 蓝牙聊天App设计1:Android Studio制作蓝牙聊天通讯软件(UI界面设计)

    前言:蓝牙聊天App设计全部有三篇文章(一.UI界面设计,二.蓝牙搜索配对连接实现,三.蓝牙连接聊天),这篇文章是一.UI界面设计 课程1:Android Studio小白安装教程,以及第一个Andr ...

  4. Android Studio开发——蓝牙聊天功能

    Android Studio开发--蓝牙聊天功能 蓝牙工作流程 功能要求 实现要点 声明蓝牙权限 添加程序运行的状态描述文本及配色代码 布局文件 蓝牙会话的服务组件ChatService Activi ...

  5. 基于Android Studio经典蓝牙APP---继上一次的完善版

    基于Android Studio经典蓝牙APP-继上一次的完善版 考虑到好友网友们反馈的问题总结了以下几点: 1.工程下载爆红:版本问题-gradle:4.1.1. 2.无接收数据功能,怎么实现:这里 ...

  6. Android Studio开发蓝牙应用(二)

    Android Studio开发蓝牙应用(二) 实现的功能 与蓝牙模块HC-06交换信息 过程 新建Empty Activity 创建布局 activity_btread_and_write.xml ...

  7. android蓝牙传输脉冲,一种基于Android操作系统的激光测距仪蓝牙通信方法与流程...

    本发明属于无线通信技术领域,涉及Android操作系统的应用,具体涉及一种基于Android操作系统的激光测距仪蓝牙通信方法. 背景技术: 目前,随着智能设备的普及,智能操作系统得到了极大的发展,An ...

  8. Android Studio开发蓝牙应用(一)

    Android Studio开发蓝牙应用(一) 环境 window 11 安卓12 HC-06蓝牙模块 创建空project 选择Empty Activity,后点击Next 可修改项目名,自定义,后 ...

  9. Android -传统蓝牙通信聊天

    概述 Android 传统蓝牙的使用,包括开关蓝牙.搜索设备.蓝牙连接.通信等. 详细 代码下载:http://www.demodashi.com/demo/10676.html 原文地址: Andr ...

最新文章

  1. QS世界大学学科排名公布,清华22个学科进入世界50强
  2. 推荐系统算法工程师培养计划:博导级教研团队,原理教学、项目实践、大厂内推的一站式培训...
  3. HTML5-SVG-嵌入到html的几种方式
  4. 从源码角度看Android系统init进程启动过程
  5. CSS绘制放大缩小关闭按钮
  6. FineReport单行与数据库交互的方法
  7. 笔试知识点 网络安全_安全点
  8. 使用selenium进行密码破解(绕过账号密码JS加密)
  9. linux brctl命令,Linux中brctl命令起什么作用呢?
  10. GOF之结构型模式Ⅰ(重点)
  11. 反射 字段_java核心基础之反射
  12. VUE颜色选择器插件vColorPicker
  13. 旧手机别扔,手把手教你DIY一台Linux服务器
  14. 自然语言处理NLP星空智能对话机器人系列:GavinNLP星空对话机器人Transformer课程片段1到片段4
  15. Windows XP SP3安装教程(图)
  16. h5移动端开发中配置真机测试
  17. 托福高频真词List17 // 附托福TPO阅读真题
  18. “我36岁了,还得对28岁的领导赔笑脸”:中年人的职场,心酸自知
  19. C/C++的内存分配?栈和堆的区别?为什么栈快?
  20. wordpress主题_选择完美的WordPress主题–您应该考虑的9件事

热门文章

  1. 做玫瑰花的方法 用纸_史上最简单的纸玫瑰花的折法教程教你用纸编法做玫瑰花...
  2. 《Java8实战》读书笔记10:组合式异步编程 CompletableFuture
  3. 9个点上10条线,每条线上3个点
  4. 从零部署 Django 项目至云服务器
  5. IC卡和ID卡的区别以及相同之处各是什么?
  6. 【分享经验】手机话费充值接口接入指南(含话费API说明)
  7. [英语歌曲]带我去月球:Fly me to the moon
  8. 慕课App inventer安安历险记 之打地鼠
  9. 这些例子有点意思,可以研究一下哈
  10. 爬取网易云,搜索指定歌曲,一段为期六天的心酸心累爬歌史。