Android蓝牙通讯

提兵百万西湖上,立马吴山第一峰!这篇文章主要讲述Android蓝牙通讯相关的知识,希望能为你提供帮助。
本文转载自:http://blog.csdn.net/vnanyesheshou/article/details/51554852
随着可穿戴设备的流行,研究蓝牙是必不可少的一门技术了。
总结了下蓝牙开发使用的一些东西分享一下。

Android蓝牙通讯

文章图片

首先需要androidManifest.xml文件中添加操作蓝牙的权限。
< uses-permissionandroid:name="Android.permission.BLUETOOTH" />
允许程序连接到已配对的蓝牙设备。
< uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN" />
允许程序发现和配对蓝牙设备。
 
操作蓝牙主要用到的类  BluetoothAdapter类,使用时导包
import android.bluetooth.BluetoothAdapter;
 
源码具体位置frameworks/base/core/Java/android/bluetooth/BluetoothAdapter.java
【Android蓝牙通讯】 
BluetoothAdapter  代表本地设备的蓝牙适配器。该BluetoothAdapter可以执行基本的蓝牙任务,例如启
 
动设备发现,查询配对的设备列表,使用已知的MAC地址实例化一个BluetoothDevice类,并创建一个
 
BluetoothServerSocket监听来自其他设备的连接请求。
 
获取蓝牙适配器
 
[java]  view plain  copy     print?
Android蓝牙通讯

文章图片
Android蓝牙通讯

文章图片
  1. BluetoothAdapter  mBluetoothAdapter  =  BluetoothAdapter.getDefaultAdapter();    
开启蓝牙
 
 
[java]  view plain  copy     print?
Android蓝牙通讯

文章图片
Android蓝牙通讯

文章图片
  1.   if(!mBluetoothAdapter.isEnabled()){   
  2. //弹出对话框提示用户是后打开   
  3. Intent  enabler  =  new  Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);    
  4. startActivityForResult(enabler,  REQUEST_ENABLE);    
  5.             //不做提示,直接打开,不建议用下面的方法,有的手机会有问题。   
  6.             //  mBluetoothAdapter.enable();    
  7. }   
获取本地蓝牙信息
 
[java]  view plain  copy     print?
  1. //获取本机蓝牙名称   
  2. String  name  =  mBluetoothAdapter.getName();    
  3. //获取本机蓝牙地址   
  4. String  address  =  mBluetoothAdapter.getAddress();    
  5. Log.d(TAG,"bluetooth  name  ="+name+"  address  ="+address);    
  6. //获取已配对蓝牙设备   
  7. Set< BluetoothDevice>   devices  =  mBluetoothAdapter.getBondedDevices();    
  8. Log.d(TAG,  "bonded  device  size  ="+devices.size());    
  9. for(BluetoothDevice  bonddevice:devices){   
  10.         Log.d(TAG,  "bonded  device  name  ="+bonddevice.getName()+"  address"+bonddevice.getAddress());    
  11. }   
打印:
 
 
[java]  view plain  copy     print?
  1. D/MainActivity(16800):  bluetooth  name  =Coolpad  8297  address  =18:DC:56:D2:30:BD   
  2. D/MainActivity(16800):  bonded  device  size  =1   
  3. D/MainActivity(16800):  bonded  device  name  =小米手机  addressF8:A4:5F:02:B1:8F   
 
 
搜索设备
mBluetoothAdapter.startDiscovery();
开始搜索设备,该过程是异步的,通过下面注册广播接受者,可以监听是否搜到设备。
[java]  view plain  copy     print?
Android蓝牙通讯

文章图片
Android蓝牙通讯

文章图片
  1. IntentFilter  filter  =  new  IntentFilter();    
  2. //发现设备   
  3. filter.addAction(BluetoothDevice.ACTION_FOUND);    
  4. //设备连接状态改变   
  5. filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);    
  6. //蓝牙设备状态改变   
  7. filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);    
  8. registerReceiver(mBluetoothReceiver,  filter);    
监听扫描结果
 
[java]  view plain  copy     print?
Android蓝牙通讯

文章图片
Android蓝牙通讯

文章图片
  1. private  BroadcastReceiver  mBluetoothReceiver  =  new  BroadcastReceiver(){   
  2.                 @Override   
  3.                 public  void  onReceive(Context  context,  Intent  intent)  {   
  4.                         String  action  =  intent.getAction();    
  5.                         Log.d(TAG,"mBluetoothReceiver  action  ="+action);    
  6.                         if(BluetoothDevice.ACTION_FOUND.equals(action)){//每扫描到一个设备,系统都会发送此广播。   
  7.                                 //获取蓝牙设备   
  8.                                 BluetoothDevice  scanDevice  =  intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);    
  9.                                 if(scanDevice  ==  null  ||  scanDevice.getName()  ==  null)  return;    
  10.                                 Log.d(TAG,  "name="+scanDevice.getName()+"address="+scanDevice.getAddress());    
  11.                                 //蓝牙设备名称   
  12.                                 String  name  =  scanDevice.getName();    
  13.                                 if(name  !=  null  & &   name.equals(VnApplication.BLUETOOTH_NAME)){   
  14.                                         mBluetoothAdapter.cancelDiscovery();    
  15.                                         //取消扫描   
  16.                                         mProgressDialog.setTitle(getResources().getString(R.string.progress_connecting));                                       //连接到设备。   
  17.                                         mBlthChatUtil.connect(scanDevice);    
  18.                                 }   
  19.                         }else  if  (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){   
  20.    
  21.                         }   
  22.                 }   
  23.                    
  24.         };    
 
mBlthChatUtil.connect(scanDevice)连接到设备,
此方法中主要是获取socket客户端,并连接。
BluetoothSocket   mmSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
mmSocket.connect();
 

当然有客户端就有服务端了,服务端应先开启,并一直等待客户端连接。直到连接成功。
 
[java]  view plain  copy     print?
Android蓝牙通讯

文章图片
Android蓝牙通讯

文章图片
  1. private  class  AcceptThread  extends  Thread  {   
  2.                 //  serverSocket   
  3.                 private  final  BluetoothServerSocket  mServerSocket;    
  4.                 public  AcceptThread()  {                     
  5.                         BluetoothServerSocket  tmp  =  null;    
  6.                         //  创建一个新的侦听服务器套接字   
  7.                         try  {   
  8.                                 tmp  =  mAdapter.listenUsingRfcommWithServiceRecord(NAME,  MY_UUID);    
  9.                         }  catch  (IOException  e)  {   
  10.                                 Log.e(TAG,  "listen()  failed",  e);    
  11.                         }   
  12.                         mServerSocket  =  tmp;    
  13.                 }   
  14.    
  15.                 public  void  run()  {   
  16.                         if  (D)  Log.d(TAG,  "BEGIN  mAcceptThread"  +  this);    
  17.                         setName("AcceptThread");    
  18.                         BluetoothSocket  socket  =  null;    
  19.                         //  循环,直到连接成功   
  20.                         while  (mState  !=  STATE_CONNECTED)  {   
  21.                                 try  {   
  22.                                         //  这是一个阻塞调用和将只返回一个   
  23.                                         //  成功的连接或例外   
  24.                                         socket  =  mServerSocket.accept();    
  25.                                 }  catch  (IOException  e)  {   
  26.                                         Log.e(TAG,  "accept()  failed",  e);    
  27.                                         break;    
  28.                                 }   
  29.                                 //  如果连接被接受   
  30.                                 if  (socket  !=  null)  {   
  31.                                         synchronized  (BluetoothChatUtil.this)  {   
  32.                                                 switch  (mState)  {   
  33.                                                 case  STATE_LISTEN:   
  34.                                                 case  STATE_CONNECTING:   
  35.                                                         //  正常情况。启动连接螺纹。   
  36.                                                         connected(socket,  socket.getRemoteDevice());    
  37.                                                         break;    
  38.                                                 case  STATE_NONE:   
  39.                                                 case  STATE_CONNECTED:   
  40.                                                         //  没有准备或已连接。socket终止。   
  41.                                                         try  {   
  42.                                                                 socket.close();    
  43.                                                         }  catch  (IOException  e)  {   
  44.                                                                 Log.e(TAG,  "Could  not  close  unwanted  socket",  e);    
  45.                                                         }   
  46.                                                         break;    
  47.                                                 }   
  48.                                         }   
  49.                                 }   
  50.                         }   
  51.                         if  (D)  Log.i(TAG,  "END  mAcceptThread");    
  52.                 }   
  53.         }   

当连接成功后,connected(mmSocket, mmDevice); 获取输入输出流,从而进行通信。
 
private   InputStream mmInStream = socket.getInputStream();
private   OutputStream mmOutStream =socket.getOutputStream();
 
mmOutStream.write(buffer); 发送信息。
mmInStream.read(buffer); 收到消息。
 
有时候扫描不到设备,需要设备蓝牙可见,这样才能被搜索到。
设置蓝牙可见性
 
[java]  view plain  copy     print?
Android蓝牙通讯

文章图片
Android蓝牙通讯

文章图片
  1. Intent  discoveryIntent  =  new  Intent(   
  2.         BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);    
  3. discoveryIntent.putExtra(   
  4. BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,  300); //时间300s,   
  5. startActivity(discoveryIntent);    

demo下载

    推荐阅读