Keep It Simple Stupid

Android: the missing bytes

| comments

TL;DR: don’t forget to RTFM (auto-steps while building).

So, an Android project sends an image (from res/drawable-mdpi/ directory) over Bluetooth to another device. To check that the file is sent correctly, I naturally compare the file sizes (and hashes after that) here and there. Somewhat a hundred bytes is missing after the transfer. Not considering possible bugs on the other side (a Bluetooth sniffer confirms not all data is actually sent), I try removing the last byte from the image, and surprise surprise… the transfer is correct.

That is:

sent: 5000 bytes; received 4920 bytes;

sent: 4999 bytes; received 4999 bytes;

Weird, isn’t it? Digging deeper, I came to the code that reads bytes of an image resource:

is = getResources().openRawResource(resource);
ByteArrayOutputStream os = new ByteArrayOutputStream(is.available());
final int buffersize = 4096;
final byte[] buffer = new byte[buffersize];
int available = 0;
while ((available = >= 0) {
    os.write(buffer, 0, available);
return os.toByteArray();

And the number of bytes corresponds to that of received on the other end! Finally, I’ve come across this text:

Note: Bitmap files may be automatically optimized with lossless image compression by the aapt tool during the build process. For example, a true-color PNG that does not require more than 256 colors may be converted to an 8-bit PNG with a color palette. This will result in an image of equal quality but which requires less memory. So be aware that the image binaries placed in this directory can change during the build. If you plan on reading an image as a bit stream in order to convert it to a bitmap, put your images in the res/raw/ folder instead, where they will not be optimized.

Sending an icon from res/raw/ directory shows that everything is OK. RTFM!