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

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

Android蓝牙通讯【转】_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


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

 

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

 

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

 

获取蓝牙适配器

 

1. BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

开启蓝牙

 

 


1. if(!mBluetoothAdapter.isEnabled()){  
2. //弹出对话框提示用户是后打开
3. Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
4. startActivityForResult(enabler, REQUEST_ENABLE);
5. //不做提示,直接打开,不建议用下面的方法,有的手机会有问题。
6. // mBluetoothAdapter.enable();
7. }

获取本地蓝牙信息

 


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. "bonded device name ="+bonddevice.getName()+" address"+bonddevice.getAddress());
11. }

打印:

 

 


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();

开始搜索设备,该过程是异步的,通过下面注册广播接受者,可以监听是否搜到设备。


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);

监听扫描结果

 



1. private BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver(){
2. @Override
3. public void onReceive(Context context, Intent intent) {
4. String action = intent.getAction();
5. "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. "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. //连接到设备。
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();

 

当然有客户端就有服务端了,服务端应先开启,并一直等待客户端连接。直到连接成功。

 



1. private class AcceptThread extends Thread {
2. // serverSocket
3. private final BluetoothServerSocket mServerSocket;
4. public AcceptThread() {
5. null;
6. // 创建一个新的侦听服务器套接字
7. try {
8. tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
9. catch (IOException e) {
10. "listen() failed", e);
11. }
12. mServerSocket = tmp;
13. }
14.
15. public void run() {
16. if (D) Log.d(TAG, "BEGIN mAcceptThread" + this);
17. "AcceptThread");
18. null;
19. // 循环,直到连接成功
20. while (mState != STATE_CONNECTED) {
21. try {
22. // 这是一个阻塞调用和将只返回一个
23. // 成功的连接或例外
24. socket = mServerSocket.accept();
25. catch (IOException e) {
26. "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. "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); 收到消息。

 

有时候扫描不到设备,需要设备蓝牙可见,这样才能被搜索到。

设置蓝牙可见性

 



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

​​demo下载​​