Android蓝牙消息收发示例代码三大技术疑问解析
Android蓝牙ConnectedThread代码疑问解答
问题1:消息接收的位置与获取方式
注释里说“发送到UI Activity”是因为示例中的handler是绑定了UI线程消息队列的Handler(通常在UI Activity中创建,用Looper.getMainLooper()初始化)。sendToTarget()确实是把消息发送给这个Handler的目标队列,最终会在UI线程的handleMessage()方法中被处理。
要获取接收的消息,你需要在创建Handler时重写handleMessage()方法,根据消息类型(MESSAGE_READ/MESSAGE_WRITE等)处理数据:
private Handler handler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { switch (msg.what) { case MessageConstants.MESSAGE_READ: byte[] readBytes = (byte[]) msg.obj; int receivedLength = msg.arg1; // 把字节转成字符串或其他格式,更新UI String content = new String(readBytes, 0, receivedLength); tvReceived.setText(content); break; case MessageConstants.MESSAGE_WRITE: // 处理发送成功的通知,比如更新日志 break; case MessageConstants.MESSAGE_TOAST: String toastText = msg.getData().getString("toast"); Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); break; } } };
问题2:write方法的调用范围与私有内部类的处理
- 不是只能在MainActivity中调用,注释的意思是建议从UI线程触发调用(避免阻塞蓝牙操作所在的子线程)。
- 因为
ConnectedThread是私有内部类,外部类(包括MainActivity)无法直接访问它的方法,所以必须在它的父类(比如管理蓝牙连接的BluetoothService类)中编写公共包装方法:
// 父类中的公共方法,供外部调用 public void sendBluetoothData(byte[] data) { if (mConnectedThread != null && mConnectedThread.isAlive()) { mConnectedThread.write(data); } }
之后MainActivity就可以通过父类实例调用这个公共方法,间接触发write()操作。
问题3:与manageMyConnectedSocket方法的关联
完全相关,manageMyConnectedSocket(socket)是Google文档里的占位方法,实际作用就是初始化并启动ConnectedThread,处理已建立连接的Socket。你需要自己实现这个方法,把Socket、输入输出流、UI线程的Handler传递给ConnectedThread:
private void manageMyConnectedSocket(BluetoothSocket socket) { InputStream inStream = null; OutputStream outStream = null; try { inStream = socket.getInputStream(); outStream = socket.getOutputStream(); } catch (IOException e) { Log.e(TAG, "获取蓝牙流失败", e); return; } // 创建并启动连接线程 mConnectedThread = new ConnectedThread(socket, inStream, outStream, handler); mConnectedThread.start(); }
当蓝牙连接成功(比如服务器端接受连接、客户端连接成功),就会调用这个方法,把后续的读写逻辑交给ConnectedThread处理。
内容的提问来源于stack exchange,提问作者TaihouKai
相关产品推荐
相关产品推荐

