why TextView can't show any data from the serial bluetooth? - android

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

Related

Android bluetooth inputstream recieve incomplete data

I am sending String "A:22.656565,76.545454#" through bluetooth.BUT At recieving time it only takes "" at first time then takes remaining String i.e "A:22.656565,76.545454#".I dont know why this occur? Any Help would be appreciated. Here is my code::
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket, String socketType) {
//Log.d(TAG, "create ConnectedThread: " + socketType);
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
//Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
mState = STATE_CONNECTED;
}
String received="" ;
public void run() {
//Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
int bytes;
while (mState == STATE_CONNECTED) {
try {
bytes = mmInStream.read(buffer);
received += new String(buffer, "UTF8");
received = received.replaceAll("\\p{C}", "");
if (received.contains("*")) {
received = received.substring(0, received.indexOf("*"));
Log.e("FOUND", ": " + received);
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, received).sendToTarget();
received = "";
buffer = new byte[1024];
}
} catch (IOException e) {
//Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
}
public void write(byte[] buffer) {
try {
//Log.d("Filter","Sending Data inside write3");
mmOutStream.write(buffer);
Log.e("FOUND456", ": " + buffer);
mHandler.obtainMessage(MESSAGE_WRITE, -1, -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);
}
}
}
Sounds like there is a small delay in receiving the data, this is not unusual. You should read data from the inputstream in a loop breaking out of the loop when the complete data is received or timeout

Xamarin Bluetooth InputStream not reading all the bytes (sometime)

I used this code to read the reply of a Bluetooth not LE device.
The solution is a Xamarin Forms project and the code is in the DependencyService.
using Android.Bluetooth;
....
public byte[] GetCommand()
{
byte[] rbuffer = new byte[200];
try
{
// Read data from the device
while (!_socket.InputStream.CanRead || !_socket.InputStream.IsDataAvailable())
{
}
int readByte = _socket.InputStream.Read(rbuffer, 0, rbuffer.Length);
}
catch (Java.IO.IOException e)
{
}
return rbuffer;
}
How is it possible to solve it?
I would use the following code instead:
//create new class for connect thread
private class ConnectedThread extends Thread {
private final InputStream mmInStream;
private final OutputStream mmOutStream;
//creation of the connect thread
public ConnectedThread(BluetoothSocket socket) {
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
//Create I/O streams for connection
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[256];
int bytes;
// Keep looping to listen for received messages
while (true) {
try {
bytes = mmInStream.read(buffer); //read bytes from input buffer
String readMessage = new String(buffer, 0, bytes);
// Send the obtained bytes to the UI Activity via handler
bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
break;
}
}
}
//write method
public void write(String input) {
byte[] msgBuffer = input.getBytes(); //converts entered String into bytes
try {
mmOutStream.write(msgBuffer); //write bytes over BT connection via outstream
} catch (IOException e) {
//if you cannot write, close the application
Toast.makeText(getBaseContext(), "Connection Failure", Toast.LENGTH_LONG).show();
finish();
}
}
}
This is working for me to get bluetooth information from an Arduino! :)

Object Input/Output Stream causes program to freeze

I am new to Object Input Streams and Object Output Streams but I have to use them to send a string over Bluetooth. Whenever I try to make the connection both phones freeze and then crash. I used the debugger and the last line it stopped at before the program froze is: tmpIn = new ObjectInputStream(socket.getInputStream());
Here is my connection thread:
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final ObjectInputStream mmInStream;
private final ObjectOutputStream mmOutStream;
private FileOutputStream mmFileOut = null;
public ConnectedThread(BluetoothSocket socket, String socketType) {
Log.d(TAG, "create ConnectedThread: " + socketType);
mmSocket = socket;
ObjectInputStream tmpIn = null;
ObjectOutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
//input stream
//mmFileIn = new FileInputStream("t.tmp");
tmpIn = new ObjectInputStream(socket.getInputStream());
//output stream
mmFileOut = new FileOutputStream("t.tmp");
tmpOut.flush();
tmpOut = new ObjectOutputStream(mmFileOut);
tmpOut.writeObject(socket.getOutputStream());
}catch (FileNotFoundException fnfe){
System.out.println("FileOutPutStream: "+ fnfe);
}catch (IOException ie){
System.out.print("ObjectOutputStream: " + ie);
}catch (Exception e){
System.out.print(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(Constants.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
// Start the service over to restart listening mode
BluetoothChatService.this.start();
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(Constants.MESSAGE_WRITE, -1, -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);
}
}
}
I read somewhere it may have to do with using .flush() on my Object Output Stream am I using that correctly?
The code in the constructor runs on the UI thread. Move it to run().

Android outputStream.write send multiple messages

is there a way to send multiple messages with OutputStream.write(bytes[]), for example when i call twice my function to write func.write("hi"); func.write(" how are you");, I receive the message "concateneted" like this: "hi how are you", but i want two different messages, is there a way to do it without using separators in my message, i mean know when the other device receives the message, here is my code (its the android bluetooth sample):
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket, String socketType) {
Log.d(TAG, "create ConnectedThread: " + socketType);
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();
// Start the service over to restart listening mode
BluetoothChatService.this.start();
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(BluetoothChat.MESSAGE_WRITE, -1, -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);
}
}
}
Call:
mmOutStream.flush()
after each message part.
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
//send what is already in buffer
mmOutStream.flush();
// 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);
}
}
From the docs:
flush()
(Flushes this output stream and forces any buffered output bytes to be written out. The general contract of flush is that calling it is an indication that, if any bytes previously written have been buffered by the implementation of the output stream, such bytes should immediately be written to their intended destination.

How to serialize an object and then send it over bluetooth

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

Categories

Resources