当前位置: 首页 > news >正文

android 蓝牙学习笔记

蓝牙部分学习
蓝牙之间的通信需要四部分:
 1 设置蓝牙设备
  BluetoothDevice类:本地蓝牙适配器,可以发现蓝牙设备,查询帮定的设备,
                      使用已知的MAC地址实例化一个蓝牙设备建立一个                      BluetoothServerSocket
  BluetoothDevice: 远端的蓝牙设备,使用它请求远端蓝牙设备连接或是取得远端蓝牙设备的一些属性(其信息封装在bluetoothsocket中)
  bluetoothsocket: 蓝牙的套接字接口
  Bluetoothserversocket:打开服务连接来监听可能到来的请求
  Bluttoothclass: 描述一个蓝牙设备的一般特点和能力
 2 寻找设备
 3 连接设备
 4 设备之间的数据传输






具体编程实现
 1 启动蓝牙
   在构造器中取得蓝牙造配器
   BluetoothAdapter mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
   查询蓝牙设备的状态(打开)
   if(  mBluetoothAdapter.isEnabled()){
  Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent,REQUEST_ENABLE_BT);
 
    }
 2 查找设备
 3 查询已配对设备
1 Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();2 // If there are paired devices3 if (pairedDevices.size() > 0) {4     //Loop through paired devices5     for (BluetoothDevice device : pairedDevices) {6         // Add the name and address to an array adapter to show in a ListView7         mArrayAdapter.add(device.getName() + "\n" + device.getAddress());8     }9 }
 
  4 扫描设备
   1 // Create a BroadcastReceiver for ACTION_FOUND 2 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 3     public void onReceive(Context context, Intent intent) { 4         String action = intent.getAction(); 5         // When discovery finds a device 6         if (BluetoothDevice.ACTION_FOUND.equals(action)) { 7             // Get the BluetoothDevice object from the Intent 8             BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 9             // Add the name and address to an array adapter to show in a ListView10             mArrayAdapter.add(device.getName() + "\n" + device.getAddress());11         }12     }13 };14 15 // Register the BroadcastReceiver16 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);17 registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
 
  5 使能被发现
   Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);2 discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);3 startActivity(discoverableIntent);
  6. 连接设备:


  在应用程序中,想建立两个蓝牙设备之间的连接,必须实现客户端和服务器端的代码(因为任何一个设备都必须可以作为服务端或者客户端)。一个开启服务来监听,一个发起连接请求(使用服务器端设备的MAC地址)。当他们都拥有一个蓝牙套接字在同一RFECOMM信道上的时候,可以认为他们之间已经连接上了。服务端和客户端通过不同的方式或其他们的蓝牙套接字。当一个连接监听到的时候,服务端获取到蓝牙套接字。当客户可打开一个FRCOMM信道给服务器端的时候,客户端获取到蓝牙套接字。


  注意:在此过程中,如果两个蓝牙设备还没有配对好的,android系统会通过一个通知或者对话框的形式来通知用户。RFCOMM连接请求会在用户选择之前阻塞。如下图:                           


 


7. 服务端的连接:


  当你想要连接两台设备时,一个必须作为服务端(通过持有一个打开的BluetoothServerSocket),目的是监听外来连接请求,当监听到以后提供一个连接上的BluetoothSocket给客户端,当客户端从BluetoothServerSocket得到BluetoothSocket以后就可以销毁BluetoothServerSocket,除非你还想监听更多的连接请求。


  建立服务套接字和监听连接的基本步骤:


  首先通过调用listenUsingRfcommWithServiceRecord(String, UUID)方法来获取BluetoothServerSocket对象,参数String代表了该服务的名称,UUID代表了和客户端连接的一个标识(128位格式的字符串ID,相当于PIN码),UUID必须双方匹配才可以建立连接。


  其次调用accept()方法来监听可能到来的连接请求,当监听到以后,返回一个连接上的蓝牙套接字BluetoothSocket。


  最后,在监听到一个连接以后,需要调用close()方法来关闭监听程序。(一般蓝牙设备之间是点对点的传输)


  注意:accept()方法不应该放在主Acitvity里面,因为它是一种阻塞调用(在没有监听到连接请求之前程序就一直停在那里)。解决方法是新建一个线程来管理。例如:




 1 private class AcceptThread extends Thread { 2     private final BluetoothServerSocket mmServerSocket; 3     public AcceptThread() { 4         // Use a temporary object that is later assigned to mmServerSocket, 5         // because mmServerSocket is final 6         BluetoothServerSocket tmp = null; 7         try { 8             // MY_UUID is the app's UUID string, also used by theclient code 9             tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);10         } catch (IOException e) { }11         mmServerSocket = tmp;12     }13 14     public void run() {15         BluetoothSocket socket = null;16         // Keep listening until exception occurs or a socket is returned17         while (true) {18             try {19                 socket = mmServerSocket.accept();20             } catch (IOException e) {21                 break;22             }23             // If a connection was accepted24             if (socket != null) {25                 // Do work to manage the connection (in a separate thread)26                 manageConnectedSocket(socket);27                 mmServerSocket.close();28                 break;29             }30         }31     }32 33 /** Will cancel the listening socket, and cause the thread to finish */34     public void cancel() {35         try {36             mmServerSocket.close();37         } catch (IOException e) { }38     }39 }
 


8. 客户端的连接:


  为了初始化一个与远端设备的连接,需要先获取代表该设备的一个BluetoothDevice对象。通过BluetoothDevice对象来获取BluetoothSocket并初始化连接,具体步骤:


  使用BluetoothDevice对象里的方法createRfcommSocketToServiceRecord(UUID)来获取BluetoothSocket。UUID就是匹配码。然后,调用connect()方法来。如果远端设备接收了该连接,他们将在通信过程中共享RFFCOMM信道,并且connect()方法返回。例如:




 1 private class ConnectThread extends Thread { 2     private final BluetoothSocket mmSocket; 3     private final BluetoothDevice mmDevice; 4     public ConnectThread(BluetoothDevice device) { 5         // Use a temporary object that is later assigned to mmSocket, 6         // because mmSocket is final 7         BluetoothSocket tmp = null; 8         mmDevice = device; 9         // Get a BluetoothSocket to connect with the given BluetoothDevice10         try {11             // MY_UUID is the app's UUID string, also used by the server code12             tmp = device.createRfcommSocketToServiceRecord(MY_UUID);13         } catch (IOException e) { }14         mmSocket = tmp;15     }16  17 18     public void run() {19         // Cancel discovery because it will slow down the connection20         mAdapter.cancelDiscovery();21         try {22             // Connect the device through the socket. This will block23 // until it succeeds or throws an exception24             mmSocket.connect();25         } catch (IOException connectException) {26             // Unable to connect; close the socket and get out27             try {28                 mmSocket.close();29             } catch (IOException closeException) { }30             return;31         }32         // Do work to manage the connection (in a separate thread)33         manageConnectedSocket(mmSocket);34     }35 }
  注意:conncet()方法也是阻塞调用,一般建立一个独立的线程中来调用该方法。在设备discover过程中不应该发起连接connect(),这样会明显减慢速度以至于连接失败。且数据传输完成只有调用close()方法来关闭连接,这样可以节省系统内部资源。


 


9. 管理连接(主要涉及数据的传输):


  当设备连接上以后,每个设备都拥有各自的BluetoothSocket。现在你就可以实现设备之间数据的共享了。


  1> 首先通过调用getInputStream()和getOutputStream()方法来获取输入输出流。然后通过调用read(byte[]) 和write(byte[]).方法来读取或者写数据。


  2> 实现细节:以为读取和写操作都是阻塞调用,需要建立一个专用现成来管理。


  3> 




 1 private class ConnectedThread extends Thread { 2     private final BluetoothSocket mmSocket; 3     private final InputStream mmInStream; 4     private final OutputStream mmOutStream; 5  6     public ConnectedThread(BluetoothSocket socket) { 7         mmSocket = socket; 8         InputStream tmpIn = null; 9         OutputStream tmpOut = null;10         // Get the input and output streams, using temp objects because11         // member streams are final12         try {13             tmpIn = socket.getInputStream();14             tmpOut = socket.getOutputStream();15         } catch (IOException e) { }16         mmInStream = tmpIn;17         mmOutStream = tmpOut;18     }19 20     public void run() {21         byte[] buffer = new byte[1024];  // buffer store for the stream22         int bytes; // bytes returned from read()23         // Keep listening to the InputStream until an exception occurs24         while (true) {25             try {26                 // Read from the InputStream27                 bytes = mmInStream.read(buffer);28                 // Send the obtained bytes to the UI Activity29                 mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();30             } catch (IOException e) {31                 break;32             }33         }34     }35 36 /* Call this from the main Activity to send data to the remote device */37     public void write(byte[] bytes) {38         try {39             mmOutStream.write(bytes);40         } catch (IOException e) { }41     }42 43 /* Call this from the main Activity to shutdown the connection */44     public void cancel() {45         try {46             mmSocket.close();47         } catch (IOException e) { }48     }49 }




 

转载于:https://www.cnblogs.com/retacn-yue/archive/2012/09/07/2761306.html

相关文章:

  • [QT] TCP协议演示
  • content_for对应的yield
  • 四十八、Qt网络(八)TCP(二)
  • GetDlgItem用法
  • 四十七、Qt网络(七)TCP(一)
  • 四十六、Qt网络(六)UDP
  • 评估一款电子邮件营销软件的方法总结
  • 四十四、Qt网络(四)FTP(二)
  • DevExpress点滴学习--换肤
  • 四十二、Qt网络(二)HTTP编程
  • 【转贴】Oracle查询重复数据与删除重复记录方法
  • 四十三、Qt网络(三)FTP(一)
  • EJB之JPA(EntityManager)
  • 四十一、Qt网络(一)简介
  • CImageList使用指南(转)
  • SegmentFault for Android 3.0 发布
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • k个最大的数及变种小结
  • Linux链接文件
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • Redash本地开发环境搭建
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 初识 webpack
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 你不可错过的前端面试题(一)
  • 浅谈Golang中select的用法
  • 事件委托的小应用
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • #1014 : Trie树
  • #HarmonyOS:基础语法
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (145)光线追踪距离场柔和阴影
  • (C语言)逆序输出字符串
  • (搬运以学习)flask 上下文的实现
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (三)终结任务
  • (状压dp)uva 10817 Headmaster's Headache
  • .gitignore文件—git忽略文件
  • .NET 设计模式—简单工厂(Simple Factory Pattern)
  • .NET 设计一套高性能的弱事件机制
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)
  • .Net中的设计模式——Factory Method模式
  • @开发者,一文搞懂什么是 C# 计时器!
  • [ActionScript][AS3]小小笔记
  • [C# WPF] DataGrid选中行或选中单元格的背景和字体颜色修改
  • [C#][DevPress]事件委托的使用
  • [C/C++]数据结构----顺序表的实现(增删查改)
  • [Cocoa]iOS 开发者账户,联机调试,发布应用事宜
  • [CTF]2022美团CTF WEB WP
  • [Deep Learning] 神经网络基础
  • [ffmpeg] 定制滤波器
  • [hive] posexplode函数