Android蓝牙串口通讯

闲着无聊玩起了Android蓝牙模块与单片机蓝牙模块的通信,简单思路就是要手机通过蓝牙发送控制指令给单片机,并作简单的控制应用。单片机的蓝牙模块连接与程序暂且略过,此文主要描述Android手机蓝牙客户端遇到的那点破事。进入正题:

连接蓝牙设备——蓝牙客户端:

Android手机一般以客户端的角色主动连接SPP协议设备(接上蓝牙模块的数字传感器),客户端连接流程是:

1.使用registerReceiver注册BroadcastReceiver来获取蓝牙状态、搜索设备等消息;

   privateBroadcastReceiversearchDevices = newBroadcastReceiver() {

publicvoid onReceive(Context context, Intent intent) {

String action = intent.getAction();

Bundle b = intent.getExtras();

Object[] lstName = b.keySet().toArray();

//显示所有收到的消息及其细节

for(inti =0; i < lstName.length;i++) {

String keyName = lstName[i].toString();

Log.e(keyName,String.valueOf(b.get(keyName)));

}

//搜索设备时,取得设备的MAC地址

if(BluetoothDevice.ACTION_FOUND.equals(action)) {

BluetoothDevice device = intent

.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

String str= device.getName() +"|" +device.getAddress();

if(lstDevices.indexOf(str) == -1)//防止重复添加

lstDevices.add(str);// 获取设备名称和mac地址

adtDevices.notifyDataSetChanged();

}

}

};

2.使用BlueAdatper的搜索:

btAdapt.startDiscovery();
    3.在BroadcastReceiver的onReceive()里取得搜索所得的蓝牙设备信息(如名称,MAC,RSSI);
    4.通过设备的MAC地址来建立一个BluetoothDevice对象;

5.由BluetoothDevice衍生出BluetoothSocket,准备SOCKET来读写设备;

6.通过BluetoothSocket的createRfcommSocketToServiceRecord()方法来选择连接的协议/服务,这里用的    是SPP(UUID:00001101-0000-1000-8000-00805F9B34FB);

try{

btSocket=btDev.createRfcommSocketToServiceRecord(uuid);

}catch(IOException e) {

//TODOAuto-generated catch block

Log.e(TAG,"Low: Connection failed.",e);

}

成功后进行连接:

try{

btSocket.connect();

Log.e(TAG," BT connection established, data transfer linkopen.");

mangeConnectedSocket(btSocket);//自定义函数进行蓝牙通信处理

}catch(IOException e) {

Log.e(TAG," Connection failed.", e);

setTitle("连接失败..");

}

7.Connect之后(如果还没配对则系统自动提示),使用

BluetoothSocket的getInputStream()和getOutputStream()来读写蓝牙设备。

 读写可以归到一个独立线程去实现~注意:读时必须一直循环读取串口缓冲区,写可以不需要。

按以上7步逐次走过后,你就会发现Android蓝牙模块是多么的坑爹了。

出现问题:

在第6步一般初学者都会报错:执行.connect()发生异常Connection refused

此时执行不下去咯,怎么办怎么办呢?

于是边debug边网上找攻略,总算在Google出老外的一些做法,尝试了下,貌似还可行。也即把

btSocket的建立方法采用另一种方法替代,这里都使用端口1

Method m;

try{

m =btDev.getClass().getMethod("createRfcommSocket",newClass[] {int.class});

   btSocket=(BluetoothSocket) m.invoke(btDev,Integer.valueOf(1));

}catch(SecurityException e1) {

//TODOAuto-generated catch block

e1.printStackTrace();

}catch(NoSuchMethodException e1) {

//TODOAuto-generated catch block

e1.printStackTrace();

}catch(IllegalArgumentException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}catch(IllegalAccessException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}catch(InvocationTargetException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}

至此,这个问题貌似倒也解决了,程序继续往下跑。

但这里请记住之前的异常,先别急着抛开~人家不一定一直都是异常哦

接下来的任务是,让手机通过蓝牙跟单片机的蓝牙模块通信,并发送数据,通过电脑串口调试助手显示出来。具体实现,在mangeConnectedSocket(btSocket)方法中实现,里面通过启动另一个Activity实现。不是重点,略过。

直到这里,我们都只是把手机蓝牙模块充当客户端来使用,那什么时候会用到服务端呢?其实,之前手机蓝牙与单片机蓝牙模块的通信,单片机蓝牙模块就充当了服务端(处于监听状态,被手机蓝牙连接)。为了更好地搞清楚Android蓝牙通信,我们接下来使用2个手机的蓝牙进行通信。简单地说,就是做一个“手机蓝牙扣扣”,⊙﹏⊙b汗

一开始就想天真地把之前的程序同时烧到2部手机中,发现只有一部手机能正常建立socket连接(主动连接的那台),而另一部却迟迟没有响应。原因很简单,服务端的程序还没有编写!

于是,开始服务端程序:开辟一个新的线程实现

连接蓝牙设备——蓝牙服务端:

   classAcceptThreadextendsThread {

privatefinal BluetoothServerSocket serverSocket;

publicAcceptThread() {

// Use a temporary object that is later assignedto mmServerSocket,

// because mmServerSocket isfinal

BluetoothServerSocket tmp=null;

try{

//tmp =btAdapt.listenUsingRfcommWithServiceRecord("MyBluetoothApp",uuid);

Log.e(TAG,"++BluetoothServerSocketestablished!++");

Method listenMethod =      btAdapt.getClass().getMethod("listenUsingRfcommOn",

new  Class[]{int.class});

tmp= ( BluetoothServerSocket) listenMethod.invoke(btAdapt,                                               Integer.valueOf( 1));

}catch(SecurityException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}catch(IllegalArgumentException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}catch(NoSuchMethodException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}catch(IllegalAccessException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}catch(InvocationTargetException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}

serverSocket=tmp;

}

publicvoid run() {

// Keep listening until exception occurs or asocket is returned

//mState!=STATE_CONNECTED

while(true){//这里是一直循环监听,也可以设置mState来判断

try{

socket= serverSocket.accept();

Log.e(TAG,"++BluetoothSocket established! DataLinkopen.++");

}catch(IOException e) {

break;

}

// If a connection was accepted

if(socket!= null){

// Do work to manage the connection (in a separatethread)

manageConnectedSocket();

try{

serverSocket.close();

}catch(IOException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}

break;

}

}

}

publicvoid cancel() {

try{

serverSocket.close();

}catch(IOException e) { }

}

}

安装测试:当2部手机都装上并打开同样的程序后,通过蓝牙检索并连接,经测试可以成功连接上,双双进入“聊天界面”,嘿嘿

注意,这时候重新拾回之前那个异常,把socket连接建立的方法重新改为

btSocket=btDev.createRfcommSocketToServiceRecord(uuid);//客户端

对应的服务端程序:

tmp=btAdapt.listenUsingRfcommWithServiceRecord("MyBluetoothApp",uuid);//服务端

这样继续重新运行安装测试,在2部手机上运行发现之前那个bug消失了~2部手机又双双进入聊天界面。

神奇~

存在bug

任一一部手机都只能成功启动一次作为客户端的主动连接,当退出聊天界面回到主界面时(服务端的AcceptThread还在继续运行着),可再次主动连接另一部手机时就又报异常Connection refused。也就是说客户端的蓝牙套接字2次连接时出错~哎(注意我的客户端蓝牙连接程序是没有放到一个独立线程,而是放到一个按钮监听事件中)

又折腾了好久,没发现个所以然来,看来连完一次退出再连时就只好重启程序咯。有哪位大神知道为什么的麻烦告知下哈!

Android蓝牙通信相关推荐

  1. Android 蓝牙通信开发

    Android 蓝牙通信开发 Receiver的设置 一.Receiver1(蓝牙状态的改变通过广播接收) 二.Receiver2(蓝牙搜索到设备.绑定设备(配对)通过广播接收) 服务端代码 客户端代 ...

  2. Android 蓝牙通信

    Android 蓝牙通信 一.现在的无线通信方案及差别 二.蓝牙传输功能开发 1.准备阶段 1)权限 2)蓝牙的开启/关闭/状态 判断设备是支持蓝牙 获取蓝牙状态 启动/关闭 2.查找设备 1) 让设 ...

  3. Android蓝牙通信具体解释

    蓝牙通信的大概过程例如以下: 1.首先开启蓝牙 2,搜索可用设备 3,创建蓝牙socket.获取输入输出流 4,读取和写入数据 5.断开连接关闭蓝牙 还要发送配对码发送进行推断! 以下是全部的源码:不 ...

  4. Qt on Android 蓝牙通信开发

    版权声明:本文为MULTIBEANS ORG研发跟随文章,未经MLT ORG允许不得转载. 最近做项目,需要开发安卓应用,实现串口的收发,目测CH340G在安卓手机上非常麻烦,而且驱动都是Java版本 ...

  5. android 蓝牙通信编程

    http://blog.csdn.net/yudajun/article/details/8362916 公司项目涉及蓝牙通信,所以就简单的学了学,下面是自己参考了一些资料后的总结,希望对大家有帮助. ...

  6. android 输出字节数组,Android蓝牙通信字节数组的数据类型转换 求教!

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 单片机和安卓手机进行蓝牙通信,发送电压数据到手机,恰好每次8位数据(1字节)传给上位机.采用以下代码获得16进制字符输出,以下是蓝牙通信接收并显示数据部分 ...

  7. android蓝牙通信_Flutter通过BasicMessageChannel实现Flutter 与Android iOS 的双向通信

    题记: --不到最后时刻,千万别轻言放弃,无论结局成功与否,只要你拼博过,尽力过,一切问心无愧. 通过 Flutter 来进行移动应用开发,打包 Android .iOS 双平台应用程序,在调用如相机 ...

  8. android蓝牙通信_使用Arduino构建OLED显示屏与Android手机接口的智能手表

    背景知识视频教程 Arduino 训练营:通过项目学习​viadean.com 通过制作Arduino UNO FM收音机接收器学习Arduino I2C​viadean.com 通过构建实际应用程序 ...

  9. Android蓝牙通信功能开发

    1. 概述 Bluetooth 是几乎现在每部手机标准配备的功能,多用于耳机 mic 等设备与手机的连接,除此之外,还可以多部手机之间建立 bluetooth 通信,本文就通过 SDK 中带的一个聊天 ...

最新文章

  1. 了不起的程序员们,瞧,这是为你们准备的 2021 年度惊喜!
  2. Android ListView 滚动翻页效果
  3. c语言实验设计报告,C语言实验设计报告.doc
  4. 征战蓝桥 —— 2013年第四届 —— C/C++A组第4题——颠倒的价牌
  5. 清零 css,css样式清零及常用类
  6. (摘要)新基建风口下,今年工业互联网平台将呈现十大新特征
  7. 信息学奥赛之数学一本通_部分地区中考加分,又一批中学公布中考认可信息学特长生!...
  8. PyTorch学习—8.模型创建步骤与nn.Module属性
  9. php正则验证邮箱、手机号、姓名、身份证、特殊符号等
  10. 简单的达梦数据库使用DISTINCT去重
  11. C 语言调用python 脚本函数
  12. svnadmin命令[转]
  13. __u64等的格式化输出
  14. php自动播放mp3,html5实现背景音乐的自动播放
  15. 泰国大师赛国羽两银收官 林丹决赛不敌骆建佑
  16. html水晶按钮图片,20个纯CSS3实现的彩色透明水晶按钮
  17. 会话、Cookie、Session、url重写
  18. 职场的技术人如何做好一个公众号?
  19. Oracle Coherence 3.5 读书笔记之3 - 满足性能,可扩展和可用性目标
  20. 提升深度学习模型的表现,你需要这20个技巧

热门文章

  1. Edge与Safari双向同步书签
  2. 最近网上比较火的虎年西游记金钱豹头像制作小程序源码
  3. 【基于ECharts 数据可视化展示相关配置表全】
  4. MEX and Increments
  5. 拼手气红包算法_线段切割法
  6. 漫画 | 如何让程序员顺利入坑?
  7. IE安全系列:IE浏览器的技术变迁(上)
  8. 数字图像处理(6)——形态学图像处理
  9. 《C++ Primer 第5版》-11.1使用关联容器-康奈尔笔记
  10. 2018互联网月饼哪家壕,阿里腾讯网易走着瞧