I'm developing an Android app that receives an image via BluetoothSocket and I'm trying to retrieve its Bitmap by using the BitmapFactory.decodeStream() method, so something like:
// Create BluetoothSocket socket and connect
// ...
// Get input stream
InputStream inputStream = socket.getInputStream();
// Get image bitmap
Bitmap bmp = BitmapFactory.decodeStream(inputStream);
What happens is that the application gets stuck on BitmapFactory.decodeStream(). To stop the application from hanging forever I have to manually close the socket from the remote device, and only after that the image gets decoded and returned successfully, but this is not a feasible solution for my application since I want the image to be transmitted programmatically. Another thing I tried was to create a separate Thread and call decodeStream() inside of it, then call Thread.start() and then Thread.join(milliseconds) with a hard-coded amount of time to wait before killing the thread. This works but I'd like to avoid it for 2 reasons:
- I want the transfer to be as fast as possible, but in this case if the image is smaller than expected the thread takes longer than needed
- If the image is bigger than expected, the thread could finish while the data is still being processed, causing some data loss
I looked at the documentation hoping to find a way to preliminarily set the expected image size before decoding the image, so that the app knows when the data has been received correctly, something like:
// Estimate length of expected data (size of image in bytes)
byte[] numOfBytes = new byte[inputStream.available()];
inputStream.read(numOfBytes)
// Set preliminary options
BitmapFactory.Options options = new BitmapFactory.Options();
options.setExpectedImageSize(numOfBytes) // what I would ideally want: set fixed number of bytes
// to let the BitmapFactory.decodeStream() method know when
// the decoding is over
// Get image bitmap
Bitmap bmp = BitmapFactory.decodeStream(inputStream, null, options);
but such procedure doesn't seem to exist.
Is there any way I can achieve this?
CODE
Server side (C#)
// Create bluetooth socket
// ...
DataWriter writer = new DataWriter(socket.OutputStream);
// Send image byte array
writer.WriteBytes(imageByteArray);
await writer.StoreAsync();
await writer.FlushAsync();
writer.Dispose();
socket.Dispose();
Client side (Java)
// Create bluetooth socket and connect
// ...
InputStream inputStream = socket.getInputStream();
Bitmap bmp = BitmapFactory.decodeStream(inputStream);
return bmp;


When BitmapFactory.decodeStream() is ready it will close the stream. And hence the socket will be closed too. You say it hangs? Wel... hmmmm. hmmm.
That is why i said you earlier that the server should close the socket after having send the file. What is causing my image to corrupt during transfer via Bluetooth RFCOMM using FTP?
If you want to keep the connection open after a picture sent/received then you cannot use BitmapFactory.decodeStream(). –
Well that is pretty standard. You let the sever first send an integer (four bytes) indicating the lenght/amount of following bytes.
Client first reads that integer and could make a byte array with the right size where it puts the received bytes of the file. You can then use BitmapFactory.decodeByteArray(). (or something like that).