convert byte array to Bitmap Android - android

I changed the Android BluetoothChat sample project to transfer files over Bluetooth. I succesfully transfered text files and print them on a ListActivity. I want to do the same thing with an image, but couldn't make it work. There is a Handler object that sends the byte array received at the InputStream to the UserInterface. There I need to convert this bytearray to an image. I tried the following but doesn't work:
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1) {
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
myImg.setImageBitmap(BitmapFactory.decodeByteArray(readBuf, 0, readBuf.length));
//the following lines would actually display the text of the file in the ListActivity
//String readMessage = new String(readBuf, 0, msg.arg1);
//mConversationArrayAdapter.add(mConnectedDeviceName+": " + readMessage);
break;
}
}
};
The handler code that sends messages to the UI looks like following:
mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1,buffer).sendToTarget();
ANSWER
I read many other posts and I found somebody else that successfully made it work. he used a little trick that saved me. I won't give the answer here because it's explained in a better way in the questions page Sending image from android to PC via bluetooth
Thanks everybody for your help though

Try using BitmapFactory.decodeByteArray(byte[] data, int offset, int length) method to get bitmap from byte array.

Related

DataInputStream hangs on reading

I am trying to create a chat application between Android and a Windows 10 device.
I have successfully sent text from Android using DataOutputStream and read it in Windows 10 using a data reader class.
My problem is Android is not able to recognize the text from Windows. It displays the result of the datainputstream.available() function but the application hangs in case I use the readString() or the readbyte() function.
Code in Android for receiving:
DataInputStream dIn = new DataInputStream(clientSocket.getInputStream());
if(dIn.available()>0)
{
int length = dIn.readInt(); // app hangs in here
byte[] byteReceived = new byte[length];
dIn.readFully(byteReceived, 0 , length); // sometimes app hangs here
String textReceived = new String(byteReceived);
text.setText(Client Says: "+ textReceived + "\n");//
}
Data sent from Windows through datawriter:
DataWriter writer = new DataWriter(socket.OutputStream))
{
writer.UnicodeEncoding=windows.Storage.Streams.UnicodeEncoding.Utf8;
writer.ByteOrder = windows.Storage.Streams.ByteOrder.LittleEndian;
uint size =writer.MeasureString(message);
writer.WriteUint32(size);
writer.WriteString(message);
try
{
await writer.StoreAsync();
}
catch (Exception exception)
{
switch (SocketError.GetStatus(exception.HResult))
{
case SocketErrorStatus.HostNotFound:
// Handle HostNotFound Error
throw;
default:
throw;
}
}
await writer.FlushAsync();
writer.DetachStream();
}
What is the issue here?
Your dIn.readFully expects bytes and not String. Moreover, it expects the exact number of bytes, as length variable. You need to create bytes from String on the windows size and send the length of byte array as Int in first transaction. Then you need to transfer this byte array unchanged in second transaction. Try it.

Android + Arduino bluetooth communication

I have a question about android bluetooth working principle. I have an app that connects to arduino with HC-06 shield. And on receive i get new line after first char. Lets say i send from arduino
12345
and in android i see in ListView
1
2345
I believe this is about android not arduino, because i connected arduino to PC and i received correct data.
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
mConversationArrayAdapter.add(readMessage);
break;
Any ideas how to debug is it really android or maybe its arduino failing?
If you are interested i post arduino code:
void loop() // run over and over
{
if (mySerial.available())
Serial.write(mySerial.read());
if (Serial.available())
mySerial.write(Serial.read());
}
EDIT
The problem about "\n" comes out only with arduino+HC-06 bluetooth shield. While connected to pc the android tablet shows correct data.
The answer was to check string ending.
private void onBluetoothRead(byte[] buffer, int len) {
String output = new String(buffer, 0, len); // Add read buffer to new string
Log.i(LOGGER_TAG, String.format("Received: "+ output + " , " + "%d bytes", len));
outputTemp += output;
if (outputTemp.endsWith("\n")){
m_deviceOutput.append(outputTemp); // Add (not replace) string to TextView
StringTokenizer splitStr = new StringTokenizer(outputTemp, ","); // split string by comma
String numberOne = splitStr.nextToken().replaceAll("\\D+",""); // First split string
String numberTwo = splitStr.nextToken().replaceAll("\\D+",""); // Second split string
m_deviceOutputPrs.setText(numberOne);
m_deviceOutputSpeed.setText(numberTwo);
outputTemp = "";
}
}
Seems like you need more time to receive the whole message. You may either append data to the same buffer, not the new one; or you may add a small delay between the time you detected new input data and the time you read the whole input data.

Google Multiplayer RealTime socket streams

I wonder if someone used RealTime sockets with Google Multiplayer (rather than messages).
I have a code that works OK with streams derived from "native"(IP) socket, so I expected it to work with RealTime socket streams too. Unfortunately this is not the case.
The following code works fine with RealTime sockets
Sending end:
int s1, s2;
os.write(new byte[] {(byte)s1, (byte)s2};
os.flush(); // May be redundant, according to Google docs
Receiving end:
byte[] buffer = new byte[2];
is.read(buffer);
int r1=buffer[0] & 0xff;
int r2=buffer[1] & 0xff;
However, since the length of chuck is unknown in advance, I prefer to spit the chunk into two pieces: length and the data, read one after another. Consider therefore a different code:
Sending end:
byte s1, s2;
os.write(s1);
os.write(s2);
os.flush();
Receiving end:
int r1=is.read();
int r2=is.read();
In this case, only first byte is read, while the second byte never comes!
Since Android docs don't recommend flush, I tried to make a wrapper for caching several writes into one on flush:
public class OutputStreamWrapper extends OutputStream {
private OutputStream innerOs;
private ByteArrayOutputStream baos;
public OutputStreamWrapper(OutputStream innerOs) {
this.innerOs = innerOs;
baos = new ByteArrayOutputStream();
}
#Override
public void write(int oneByte) throws IOException {
baos.write(oneByte);
}
#Override
public void flush() throws IOException {
if (baos.size() > 0)
innerOs.write(baos.toByteArray());
baos.reset();
}
#Override
public void write(byte[] buffer, int offset, int count)
throws IOException {
baos.write(buffer, offset, count);
}
#Override
public void close() throws IOException {
flush();
innerOs.close();
baos.close();
}
}
The problem persists!
Am I doing something wrong?
If I can't find the solution, I will have to write custom streams as wrappers for Real-Time Messages, but it is really a shame to avoid "ready to use" streams.
No answer for two months... Have to answer it somehow :)
I tried several approaches, but couldn't get it working. Either the implementation of RealTime sockets is broken (BTW, I haven't come across any example of using those), or I still misunderstand something.
As a result, I found nothing better than making my own RealTime sockets by sending messages (reliable or unreliable, depending on request) under the hood.
The code is so weird that I am ashamed to publish it. But this is the idea:
outputStream has a BiteArrayOuputStream of size equals to max allowed size of RealTimeMessage.
It fires a message either on flush() or when the array is full. There is an indicator of a split packet.
I keep a queue of received messages. The input streams polls the queue and after the whole packet has been collected it returns the bytes.
Works great for me!

Serial BT data from Arduino is chopped up in Android, how to solve this?

The exact problem I am having is the same as in this thread:
Why does the serial BT data I received get chopped out?
So I know I need to make delimiters and parse, which I what I need, but sadly the answer to that thread wasn't specific enough.
I need to send analog data (from 0-1023) in the Arduino over to the Android device, so I added a "n" as a delimiter to the end of each string before sending over as such:
#include <SoftwareSerial.h>
int bluetoothTx = 2;
int bluetoothRx = 3;
boolean toggle = true;
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
void setup()
{
//Setup usb serial connection to computer
Serial.begin(9600);
//Setup Bluetooth serial connection to android
bluetooth.begin(115200);
bluetooth.print("$$$");
delay(100);
bluetooth.println("U,57600,N");
bluetooth.begin(57600);
}
void loop()
{
//Read from serial to bluetooth
while(1) //to reduce jitters
{
String sensorString = String(analogRead(A0), DEC);
sensorString = sensorString + "n";
bluetooth.println(sensorString);
delay(100);
}
}
This is for the Arduino side.
For the Android side, I used the BluetoothChat example, so in the mHandler and in the switch-case of MESSAGE_READ, the codes are as such:
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
mConversationArrayAdapter.add(readMessage);
Where mConversationArrayAdapter is a String ArrayAdapter. May i know how I can modify the code within the MESSAGE_READ case so as to solve this problem?
Send a string of ascii characters formed by each nibble of 0-1023 code (2 bytes), and append it by newline character (i.e. /n). As an example if hex code to send is 0x03FF (i.e. 1023 decimal), then string to send will be 0x30,0x33,0x46,0x46,0x0A.

HC-05 + Android ( Wrong echos / data )

So I am facing a problem from a while now . Any suggestion would be good.
First I used my code to receive data from arduino , then I used the bluetoothChat and changed the uuid , I can pair , everything is good , but if I send an entire string from arduino to android I get only parts of that string.
If I use bluetooth terminal from google play everything is ok, and on the description it says it is made from the bluetooth Chat sample .
Code Arduino
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 9); //RX,TX
long int i = 0;
void setup(){
mySerial.begin(9600);
}
void loop(){
mySerial.print("This is a message n. ");
mySerial.println(i);
i++;
delay(100);
}
Android code : Bluetooth Chat Sample
Exemple of message received on Android:
Message to be sent!
So first messages I think are waiting while the module is paired .
because every time I get .
is is a message n. 466
This is a message n.467
.
. ( here I get correct messages )
.
This is a message n.470
message n. 495
.
.
and after the first messages I get messages like
ssage n.534
t
essage n.m
essage n.
535
( I neved again get an entire message )
Handler :
h = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case RECIEVE_MESSAGE: // if receive massage
byte[] readBuf = (byte[]) msg.obj;
String strIncom = new String(readBuf, 0, msg.arg1); // create string from bytes array
sb.append(strIncom); // append string
int endOfLineIndex = sb.indexOf("\r\n"); // determine the end-of-line
if (endOfLineIndex > 0) { // if end-of-line,
String sbprint = sb.substring(0, endOfLineIndex); // extract string
sb.delete(0, sb.length()); // and clear
Log.d("Arduino", "Mesaj:"+ sbprint.toString());
}
Log.d("Arduino", "...Mesaj:"+ sb.toString() + " Byte:" + msg.arg1 + "...");
break;
}
};
};
Listener to InputStream
public void run() {
byte[] buffer = new byte[256]; // 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); // Get number of bytes and message in "buffer"
h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer).sendToTarget(); // Send to message queue Handler
} catch (IOException e) {
break;
}
}
}
note you are using a software emulation of serial port, hence timing is not as good as it would be with a hardware UART.
It is likely one or both of the following two possible issues:
1) the start and stop bit are not properly timed, causing back to back bytes. Which occur when a string is set, rather then pecking in keys one at a time.
The solution would be to space out each key.
2) baud rates do not match with in tolerance. Either SLOWING DOWN or SPEEDING UP the baud rate on both the HC05 and Arduino will better match the timing.
I would also recommend ensuring your library is SoftwareSerial, states that it is NewSoftSerial. It has many issues fixed. It was implemented in to the Arduino IDE 1.0.+ core libraries, so if you have recent IDE you should have it.

Categories

Resources