I'm making a Battleships game and I want to send an Array of a class named Ships(which contains stuff like ship name, size, rotated or not and an arraylist for coordinates). I've googled this and looked on Stack overflow and I basically need to serialize the array, but this is where I'm stuck. I need to use ObjectOutputStream, but how do I encorporate that into the code below (taken from android dev site). Note I have already made the ship class implement serializable. Thanks in advance
public class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "connectedthread started");
// mHandler.obtainMessage(TEST).sendToTarget();
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created");
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
Log.i(TAG, "Begin mConnectedThread");
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
Log.i(TAG, "reaaaad msg");
mHandler.obtainMessage(SetUpGame.MESSAGE_READ2, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnectd");
break;
}
}
}
/*
* Call this from the main activity to send data to the remote
* device
*/
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
Log.i(TAG, "writeeee msg");
mHandler.obtainMessage(SetUpGame.MESSAGE_WRITE, -1,-1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write");
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close of connect socket failed");
}
}
}
and my handler:
final Handler mHandler = new Handler() {
#Override
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case MESSAGE_READ2:
byte[] readBuf = (byte[]) msg.obj;
String readMessage = new String(readBuf, 0, msg.arg1);
break;
case MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
String writeMessage = new String(writeBuf);
//Toast.makeText(getApplicationContext(),"Me:" + writeMessage, Toast.LENGTH_SHORT).show();
break;
In the code above you get input/output streams from the connected socket.
Now you can stream data to/from the socket using those streams.
How exactly you do this depends on the type of data you want to stream. In this case you have a serializable Object to send, so you will wrap your stream in a filter that adapts the stream for use with Objects: ObjectOutputStream/ObjectInputStream...
ObjectOutputStream oos = new ObjectOutputStream( mmOutStream );
for (Ship ship: ships)
oos.writeObject( ship );
This code iterates through the array of Ships, writing each ship to the stream (and hence, to the Bluetooth socket).
The receiving side is the same, with one additional complication: you don't necessarily know when to stop or what to read. There are various schemes for handling this, and there are SO questions dealing specifically with this. The Bluetooth page of the Android developer's guide has sample code for this:
http://developer.android.com/guide/topics/connectivity/bluetooth.html
Related
I'am a newbie to android Bluetooth and I want to read and store the Bluetooth message in external android app(mine) using internal storage or sqlite. I have tried the android bluetooth-chat sample from GitHub but I don't know how to implement my idea.
Any help would be helpful and thanks
Exchange of bluetooth messages is covered in the android.bluetooth section of the api.
http://developer.android.com/guide/topics/connectivity/bluetooth.html#ManagingAConnection
Here is a basic example of managing a connection and sending/receiving messages:
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
I'm trying to receive data from multiple device in same time, i'm using createInsecureRfcommSocketToServiceRecord() and the SPP UUID 00001101-0000-1000-8000-00805F9B34FB to connect to non-android devices.
So i'm running 3 instance of ConnectedThread, i'm able to write to all device, but i can't receive from 2 device at same time.
Example : i'm connecting to 2 Pc using HyperTerminal, if i send a txt file on both at the same time, i will receive only one on my android device, the other one is ignored.
I'm looking this library : http://arissa34.github.io/Android-Multi-Bluetooth-Library/ seems i have to run a server on my android phone.
How can I achieve this?
Best regards.
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
i'm using the Infamous BluetoothChat-Example from Google to receive a ByteArray.
I know his length (55bytes), his Start Byte (0x69) and his End Byte (0x16) as well as the length of the data in the Array.
I'm quite sure that the Sender sends out 55 Bytes without any interruption but on the BluethootChat Example it looks like i receive multiple data packages.
The first package consists of 0x69 followed by 1023 times 0x00.
Then i receive the rest of the 55bytes.
This happens 70% of the time, sometimes the array get spiltted in the middle and sometimes the whole array is received complete.
Is this a normal Android-Bluetooth behavior
Thanks in advance...
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
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 run() {
Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
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(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
}
This answer here answered the same question. I just had a same issue and this answer was what I found.
I need to show data to a TextView from a serial Bluetooth.
But when i connect my application with the serial device, it did connected but suddenly went forced closed. The logcat shows nothing so I don't know what's wrong.
This is the code when application listens the inputstream while connected:
public void run() {
Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
int bytes;
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
//mEmulatorView.write(buffer, bytes);
mTextView.append(new String(buffer));
// Send the obtained bytes to the UI Activity
//mHandler.obtainMessage(BlueTerm.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
String a = buffer.toString();
mTextView.setText(a);
a = "";
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
}
and TextView mTextView = (TextView) findViewById(R.id.dataTerm);
and on the layout:
<TextView
android:id="#+id/dataTerm"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
So does anyone know what went wrong?
Any answers are so helpful, thanks..
The code that finally work
On the main file, in my case named FinalSetting:
On the Activity method, declare:
//Layout View
private static TextView mTextView;
On the onCreate(Bundle savedInstanceState) method declare the textview:
mTextView = (TextView) findViewById(R.id.dataTerm);
On the Handler method:
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
//mEmulatorView.write(readBuf, msg.arg1);
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
//mConversationArrayAdapter.add(mConnectedDeviceName+": " + readMessage);
mTextView.setText(readMessage);
break;
On the BluetoothService.java file:
Let's just straight to the method
//This thread runs during a connection with a remote device.
//It handles all incoming and outgoing transmissions.
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
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 run() {
Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
//final byte[] buffer = new byte[1024];
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(FinalSetting.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
}
/**
* Write to the connected OutStream.
* #param buffer The bytes to write
*/
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
// Share the sent message back to the UI Activity
mHandler.obtainMessage(FinalSetting.MESSAGE_WRITE, buffer.length, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
After you connect to the serial Bluetooth device, the data will show up on the TextView.
Hope this help :D
Seems like you are trying to modify mTextView in a non-UI thread which is illegal and might be the reason for FC (if not any other issue). However you can achieve this as below:
Change this:
mTextView.append(new String(buffer));
To this:
mTextView.post(new Runnable() {
#Override
public void run() {
mTextView.append(new String(buffer));
}
});
I'm trying to communicate with a bluetooth device. The information I have on the device states that
"The communications protocol is ASCII, commas separate output values. The message is terminated by carriage return and line feed pair. When saved as a file using a terminal emulator these results can be read into an Excel spreadsheet."
How do I send and receive from this device? I have tried using InputStreamReader and OutputStreamWriter, but I don't think that's working.
EDIT:
for sending data I'm trying:
public void send(String s){
try {
writer.write(s);
} catch (IOException e) {
e.printStackTrace();
}
}
where
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
inStream = tmpIn;
writer = new OutputStreamWriter(tmpOut);
You can also see there where I am using inStream that is a simple InputStream. I have also tried InputStreamReader, but I just got random characters back. With the InputStream I am only reading 4 bytes no matter what I send the device, so I'm not sure if even the sending is working.
What should I be using? Thanks!
You should take a look at Java documentation on IO Streams to make the whole picture.
For retrieval I assume you are using InputStream.read() method, which reads one byte at a time. To retrieve several bytes at a time you should use byte[] buffer. But that's not your case, just FYI.
In your case you don't need to use InputStream methods, but InputStreamReader instead, because
Reader operates on characters, not bytes. As stated in your quotation of protocol description, you have separate lines of ASCII. In this situation BufferedReader is handy, because it has readLine() method.
So you can just
in = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
And then
String line = br.readLine();
For sending data you should use OutputStreamWriter.
REMEMBER:Please close streams after use!!! in finaly{} clause
I am following up on this in case anyone else is having the same problems. One of the problems I was having was that the device I was trying to communicate with was expecting a specific order of /n and /r and would lock up if that was incorrect so I had no was of knowing if it was working or not.
Here is he code I use for sending and receiving, I have used it on a couple of devices now and it seems to work well.
/**
* This thread runs during a connection with a remote device.
* It handles all incoming and outgoing transmissions.
*/
private class ConnectedThread extends Thread {
private final BluetoothSocket socket;
private final InputStream inStream;
private final OutputStream outStream;
private final DataInputStream datIn;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "create ConnectedThread");
this.socket = 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);
}
inStream = tmpIn;
outStream = tmpOut;
datIn = new DataInputStream(inStream);
}
public void run() {
Log.i(TAG, "BEGIN ConnectedThread");
Bundle data = new Bundle();
// Keep listening to the InputStream while connected
while (true) {
Log.i(TAG, "Reading...");
try {
// Read from the InputStream
String results;
Log.i(TAG, "Recieved:");
results = datIn.readLine();
Log.i(TAG, results);
// Send the obtained bytes to the UI Activity
data.putString("results", results);
Message m = handler.obtainMessage(); // get a new message from the handler
m.setData(data); // add the data to the message
m.what = MESSAGE_READ;
handler.sendMessage(m);
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
handler.obtainMessage(MESSAGE_DISCONNECTED).sendToTarget();
setState(STATE_NONE);
// Start the service over to restart listening mode
break;
}
}
}
/**
* Write to the connected OutStream.
* #param buffer The bytes to write
*/
public void write(byte[] buffer) {
try {
outStream.write(buffer);
Log.i(TAG, "Sending: " + new String(buffer));
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
/**
* Write to the ConnectedThread in an unsynchronized manner
* #param out The bytes to write
* #see ConnectedThread#write(byte[])
*/
public void send(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (state != STATE_CONNECTED) return;
r = connectedThread;
}
// Perform the write unsynchronized
r.write(out);
}