Android – 通过蓝牙传递对象

Android的蓝牙聊天示例对于学习如何在手机之间传递字符串非常有用 – 是否可以使用相同的代码在手机之间传递对象? 我在两部手机中定义了相同的类,我只想将一个类的实例从一个手机传递到另一个手机。 有可用的示例代码吗? 我尝试使用序列化并在chatoutputstream和objectinputstream的聊天示例中替换outputstream和inputstream,但它似乎不起作用

我发现处理此问题的最佳方法如下:

  1. 我将我的对象设置为实现我想发送的Serializable。
  2. 我设置以下代码来管理消息:

    public byte[] serialize() throws IOException { ByteArrayOutputStream b = new ByteArrayOutputStream(); ObjectOutputStream o = new ObjectOutputStream(b); o.writeObject(this); return b.toByteArray(); } //AbstractMessage was actually the message type I used, but feel free to choose your own type public static AbstractMessage deserialize(byte[] bytes) throws IOException, ClassNotFoundException { ByteArrayInputStream b = new ByteArrayInputStream(bytes); ObjectInputStream o = new ObjectInputStream(b); return (AbstractMessage) o.readObject(); 
  3. 我更改了write语句以接受Serializable,然后进行最后的写入:

     /** * Write to the connected OutStream. * @param buffer The bytes to write */ public void write(AbstractMessage buffer) { try { Log.v(TAG,"Writing \""+(buffer.serialize())+"\""); mmOutStream.write(buffer.serialize()); // Share the sent message back to the UI Activity mHandler.obtainMessage(AbstractMessageManager.MESSAGE_WRITE, -1, -1, buffer) .sendToTarget(); } catch (IOException e) { Log.e(TAG, "Exception during write", e); } } 

蓝牙聊天示例演示了如何使用基于RFCOMM的串行端口配置文件(SPP)。 建立连接后,您可以串行发送任何您喜欢的数据; 您只需要能够将对象表示为串行的字节流,即序列化它们。

因此,使用序列化肯定是通过链接发送对象的一种方式。 蓝牙API的发送和接收函数处理字节数组,但您可以轻松调整蓝牙聊天示例以使用流,例如,发送函数将从流中读取字节并将它们放入数组缓冲区,然后发送该缓冲区然后,应用程序代码将简单地通过输入和输出流管道进行通信 – 这是我过去做过的一种方式。

所以你的实际想法没有错。 更大的问题是你实施它的方式不对,更问题的还在于你提出问题的方式也很差。 您需要更准确地描述不起作用的内容,解释您已经尝试过的调试,并发布代码示例和Logcat输出,以便我们可以正确地帮助您。

最后,我确实发现了我认为蓝牙聊天代码示例中的错误:数据接收函数将接收字节数组的引用传递给用于显示接收到的每行文本的ArrayList。 当传输少量慢速文本时,这是正常的,但是当您尝试发送大量数据时,您开始看到数据被破坏,可能是因为ArrayList适配器仍然在读取相同数组的字节时数组正在填充更新的数据。

答案是肯定的。 String是一个Object。 记得? 但究竟如何做到这一点,我仍在寻找解决方案,这就是我带到这里的原因……

Trev16v,首先,感谢您的初步反馈。

为了序列化我的对象,我使用了来自http://www.jondev.net/articles/Android_Serialization_Example_(Java )的类serializeObject和deserializeObject它们似乎运行良好:如果我序列化一个对象(由实现的类创建)来自电话/活动的Serializable)并从同一部手机反序列化我设法从生成的byte []中获取一个对象。

然后,我尝试在奥德蓝牙聊天示例中的类BluetoothChatServices中使用相同的代码将序列化对象发送到另一部手机(在该示例中有

  public ConnectedThread(BluetoothSocket socket) { Log.d(TAG, "create ConnectedThread"); mmSocket = socket; InputStream tmpIn = null; OutputStream tmpOut = null; // Get the BluetoothSocket input and output streams try { tmpIn = socket.getInputStream(); tmpOut = socket.getOutputStream(); } catch (IOException e) { Log.e(TAG, "temp sockets not created", e); } mmInStream = tmpIn; mmOutStream = tmpOut; } 

并使用传递字节

 public void write(byte[] buffer) { try { mmOutStream.write(buffer); // Share the sent message back to the UI Activity mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer) .sendToTarget(); } catch (IOException e) { Log.e(TAG, "Exception during write", e); } } 

并阅读使用

  public void run() { Log.i(TAG, "BEGIN mConnectedThread"); byte[] buffer = new byte[10240]; int bytes; // Keep listening to the InputStream while connected while (true) { try { // Read from the InputStream bytes = mmInStream.read(buffer); // Send the obtained bytes to the UI Activity mHandler.obtainMessage(BluetoothManageActivity.MESSAGE_READ, bytes, -1, buffer) .sendToTarget(); } catch (IOException e) { Log.e(TAG, "disconnected", e); connectionLost(); break; } } } 

使用BluetoothChatServices的问题在于,在另一部手机上接收的字节数组与在序列化对象上发送的字节数组不同。 例如,当发送它时,为了给出seriealized对象的一个​​想法元素[0]是= -84,我从另一个手机接收的那个元素[0]到[4] = 0,然后[5] = 4而且所有其他元素也没有对齐。 我尝试使用上面的方法编写并运行以使用ObjectInputStream和ObjectOutputstream更改Inputstream和Outputstream但是没有成功(如果这应该是实现它的方式,我可以发布我尝试使用的代码)

再次,非常感谢你的帮助,我是所有这些概念的新手,所以如果我说废话,我也很乐意接受一个教程

谢谢

遇到同样的问题……当我从一个Android设备发送一系列对象时,数据正常发送……但是在接收端,所有对象都不是从接收到的byte []构造的。

任何收到的对象都会随机出错,但是相同的代码在Java中正常工作……我认为在将数据从一个设备传输到另一个设备时,有些字节错过了…

可以使用以下代码完成可序列化对象到byte []和byte []到对象的转换

 public static byte[] toByteArray(Object obj) { byte[] bytes = null; ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(new ByteArrayOutputStream()); oos.writeObject(obj); oos.flush(); return bos.toByteArray(); } catch(Exception e) { Log.e("Bluetooth", "Cast exception at sending end ..."); } return bytes; } public static Object toObject(byte[] bytes) { Object obj = null; ObjectInputStream ois = null; try { ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); return ois.readObject(); } catch(Exception ex) { Log.e("Bluetooth", "Cast exception at receiving end ..."); } return obj; } 

我实际上发现了问题 – 使用时加载字节

 try { // Read from the InputStream bytes = mmInStream.read(buffer); 

它们实际上是按步骤加载的。在调试和单步执行代码时,我发现如果首先加载990个字节,然后是剩余的字节..所以当我回到UI处理程序时,我只看到第二步中加载的字节..

我想知道是否有办法强制一次加载所有字节