Android蓝牙通讯

Posted 请给我倒杯茶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android蓝牙通讯相关的知识,希望对你有一定的参考价值。

本文转载自:http://blog.csdn.net/vnanyesheshou/article/details/51554852

随着可穿戴设备的流行,研究蓝牙是必不可少的一门技术了。

总结了下蓝牙开发使用的一些东西分享一下。

技术分享

首先需要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

 

BluetoothAdapter 代表本地设备的蓝牙适配器。该BluetoothAdapter可以执行基本的蓝牙任务,例如启

 

动设备发现,查询配对的设备列表,使用已知的MAC地址实例化一个BluetoothDevice类,并创建一个

 

BluetoothServerSocket监听来自其他设备的连接请求。

 

获取蓝牙适配器

 

[java] view plain copy
 
 print?技术分享技术分享
  1. BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();  

开启蓝牙

 

 

[java] view plain copy
 
 print?技术分享技术分享
  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?技术分享技术分享
  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?技术分享技术分享
  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?技术分享技术分享
  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?技术分享技术分享
  1. Intent discoveryIntent = new Intent(  
  2.     BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);  
  3. discoveryIntent.putExtra(  
  4. BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);//时间300s,  
  5. startActivity(discoveryIntent);  


demo下载

以上是关于Android蓝牙通讯的主要内容,如果未能解决你的问题,请参考以下文章

delphi android蓝牙4.0开发

android 蓝牙开发---与蓝牙模块进行通讯 基于eclipse项目

Android实现和下位机蓝牙通讯

Android6.0 蓝牙通讯的实现

[RK3568][Android11]蓝牙通讯协议PhoneBookAccessProfile(PBAP)同步通讯录

[RK3568][Android11]蓝牙通讯协议PhoneBookAccessProfile(PBAP)同步通讯录