Android Bluetooth蓝牙开发:Bluetooth蓝牙设备之间数据传输(4)

迷南。 2024-02-17 16:53 76阅读 0赞



Android Bluetooth蓝牙开发:Bluetooth蓝牙设备之间数据传输(4)

附录文章3简介了Android Bluetooth蓝牙设备之间的连接建立,和Java网络编程的socket套接字连接建立一样,Android不同的Bluetooth蓝牙设备间的socket连接建立后,就可以进行数据传输了。
Android Bluetooth蓝牙的socket编程模型和Java网络编程模型类似,数据传输模型也是基于流的模型。在Java网络编程中,从一个socket套接字获得输入(InputStream)、输出流(OutputStream),进而进行服务器端和客户端的点到点的数据传输(读和写)。而Android Bluetooth蓝牙数据传输基本可以认为就是仿照Java的流模型。
附录文章3完成了两个不同蓝牙设备的socket套接字的连接,本文在附录文章3的基础上更进一步,从已经建立socket套接字的基础上获取输入输出流,从而完成一个简单的数据传输,实现一个简单的功能:Android Bluetooth蓝牙设备服务端等待客户连接请求,当外部的一个Android Bluetooth蓝牙设备传入一个连接请求并与服务器端建立连接后,服务器端就发给客户端一个简单的字符串数据比如经典的hello,world!
为了完成上述简单的字符串传输,其实就是在附录文章3的基础上、从已有的socket像Java网络编程中的socket一样获取InputStream进行数据的读、获取OutputStream进行数据的写。
还是先简单描述一下编程模型的逻辑思路划分:
(A)还是在一个蓝牙设备上部署服务器端代码,然后在一个while循环里面等待客户端连接请求。当有客户端请求进来并且建立socket连接后,服务器端就从这个socket获取OutputStream,至此,问题就简化成一般的Java流的写,然后在这个OutputStream写入hello,world!即可。
(B)在另外一个蓝牙设备上部署客户端代码。客户端代码扫描获得服务器端Android Bluetooth设备后,就发起对服务器端蓝牙设备的连接(这部分过程在我写的附录文章1中已有简介)。获得服务器端蓝牙设备后,就像我写的附录文章3那样,和服务器端建立socket连接,然后从这个socket获得InputStream,到这个阶段,问题就简化成一般的Java流的读,从这个InputStream把hello,world!读出来即可。

上述功能过程的完整代码(Android Bluetooth蓝牙服务器端):

  1. package zhangphil.bluetooth;
  2. import java.io.OutputStream;
  3. import java.util.UUID;
  4. import android.app.ListActivity;
  5. import android.bluetooth.BluetoothAdapter;
  6. import android.bluetooth.BluetoothDevice;
  7. import android.bluetooth.BluetoothServerSocket;
  8. import android.bluetooth.BluetoothSocket;
  9. import android.os.Bundle;
  10. import android.util.Log;
  11. public class MainActivity extends ListActivity {
  12. private BluetoothAdapter mBluetoothAdapter;
  13. private final String tag = "zhangphil";
  14. private final String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB";
  15. private class ServerThread extends Thread {
  16. private BluetoothServerSocket serverSocket;
  17. @Override
  18. public void run() {
  19. try {
  20. serverSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(tag, UUID.fromString(MY_UUID));
  21. } catch (Exception e) {
  22. e.printStackTrace();
  23. }
  24. Log.d(tag, "等待客户连接...");
  25. while (true) {
  26. try {
  27. BluetoothSocket socket = serverSocket.accept();
  28. BluetoothDevice device = socket.getRemoteDevice();
  29. Log.d(tag, "接受客户连接 , 远端设备名字:" + device.getName() + " , 远端设备地址:" + device.getAddress());
  30. if (socket.isConnected()) {
  31. Log.d(tag, "已建立与客户连接.");
  32. // 写数据
  33. sendDataToClient(socket);
  34. }
  35. } catch (Exception e) {
  36. e.printStackTrace();
  37. }
  38. }
  39. }
  40. // 蓝牙服务端发送简单的一个字符串:hello,world!给连接的客户
  41. private void sendDataToClient(BluetoothSocket socket) {
  42. String s = "hello,world ! by zhangphil";
  43. byte[] buffer = s.getBytes();
  44. try {
  45. OutputStream os = socket.getOutputStream();
  46. os.write(buffer);
  47. os.flush();
  48. // os.close();
  49. // socket.close();
  50. Log.d(tag, "服务器端数据发送完毕!");
  51. } catch (Exception e) {
  52. e.printStackTrace();
  53. }
  54. }
  55. }
  56. @Override
  57. protected void onCreate(Bundle savedInstanceState) {
  58. super.onCreate(savedInstanceState);
  59. mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  60. if (mBluetoothAdapter != null)
  61. new Thread(new ServerThread()).start();
  62. }
  63. }

相应的,完整的Android Bluetooth蓝牙客户端代码:

  1. package zhangphil.client;
  2. import java.io.InputStream;
  3. import java.util.UUID;
  4. import android.app.Activity;
  5. import android.bluetooth.BluetoothAdapter;
  6. import android.bluetooth.BluetoothDevice;
  7. import android.bluetooth.BluetoothSocket;
  8. import android.content.BroadcastReceiver;
  9. import android.content.Context;
  10. import android.content.Intent;
  11. import android.content.IntentFilter;
  12. import android.os.Bundle;
  13. import android.util.Log;
  14. public class MainActivity extends Activity {
  15. private BluetoothAdapter mBluetoothAdapter;
  16. private final String tag = "zhangphil";
  17. private final String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB";
  18. // 广播接收发现蓝牙设备
  19. private BroadcastReceiver mReceiver = new BroadcastReceiver() {
  20. @Override
  21. public void onReceive(Context context, Intent intent) {
  22. String action = intent.getAction();
  23. if (BluetoothDevice.ACTION_FOUND.equals(action)) {
  24. BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
  25. String name = device.getName();
  26. if (name != null)
  27. Log.d(tag, "发现设备:" + name);
  28. if (name != null && name.equals("zhangphil_pad")) {
  29. Log.d(tag, "发现目标设备,开始线程连接!");
  30. // 蓝牙搜索是非常消耗系统资源开销的过程,一旦发现了目标感兴趣的设备,可以考虑关闭扫描。
  31. mBluetoothAdapter.cancelDiscovery();
  32. new Thread(new ClientThread(device)).start();
  33. }
  34. }
  35. }
  36. };
  37. private class ClientThread extends Thread {
  38. private BluetoothDevice device;
  39. public ClientThread(BluetoothDevice device) {
  40. this.device = device;
  41. }
  42. @Override
  43. public void run() {
  44. BluetoothSocket socket = null;
  45. try {
  46. socket = device.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));
  47. Log.d(tag, "连接服务端...");
  48. socket.connect();
  49. Log.d(tag, "连接建立.");
  50. // 读数据
  51. readDataFromServer(socket);
  52. } catch (Exception e) {
  53. e.printStackTrace();
  54. }
  55. }
  56. private void readDataFromServer(BluetoothSocket socket) {
  57. byte[] buffer = new byte[64];
  58. try {
  59. InputStream is = socket.getInputStream();
  60. int cnt = is.read(buffer);
  61. is.close();
  62. String s = new String(buffer, 0, cnt);
  63. Log.d(tag, "收到服务端发来数据:" + s);
  64. } catch (Exception e) {
  65. e.printStackTrace();
  66. }
  67. }
  68. }
  69. @Override
  70. protected void onCreate(Bundle savedInstanceState) {
  71. super.onCreate(savedInstanceState);
  72. mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  73. // 注册广播接收器。接收蓝牙发现讯息
  74. IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
  75. registerReceiver(mReceiver, filter);
  76. if (mBluetoothAdapter.startDiscovery()) {
  77. Log.d(tag, "启动蓝牙扫描设备...");
  78. }
  79. }
  80. @Override
  81. protected void onDestroy() {
  82. super.onDestroy();
  83. unregisterReceiver(mReceiver);
  84. }
  85. }

注意在连接阶段设备名的区分设置,我写的这个例子,在蓝牙互相并连接阶段,是根据蓝牙设备的名字进行过滤和配对的。在我写的这个例子中,服务端的Android Bluetooth蓝牙设备名字设置成:zhangphil_pad。服务器端代码和客户端代码分别部署在不同的Android Bluetooth蓝牙设备终端。
代码运行结果如图(客户端读到的数据,logcat的输出):

Center

附录文章:

1,《Android Bluetooth蓝牙开发:发现Bluetooth蓝牙设备(1)》链接地址:http://blog.csdn.net/zhangphil/article/details/50524809
2,《Android Bluetooth蓝牙开发:Bluetooth蓝牙设备配对Paired Bluetooth Devices(2)》链接地址:http://blog.csdn.net/zhangphil/article/details/50537796
3,《Android Bluetooth蓝牙开发:Bluetooth蓝牙设备之间的连接建立(3)》链接地址:http://blog.csdn.net/zhangphil/article/details/50554415
4,Android Bluetooth蓝牙开发Google官方文档链接地址:http://developer.android.com/intl/zh-cn/guide/topics/connectivity/bluetooth.html

发表评论

表情:
评论列表 (有 0 条评论,76人围观)

还没有评论,来说两句吧...

相关阅读