简体   繁体   中英

Received byte array containing bitmap returns null

I've been trying to send an image from one device to another using the BluetoothChat sample from Google. I can send string value from device to device but I'm having problems sending images. I have two classes handling the receiving and sending of data.

For sending images, I convert the image path to bitmap then convert it to byte[] and pass that to the utility class, same as the BluetoothChat sample but with increased buffer size (1024 default, changed it to 8192). My code for the BluetoothSend class that sends data to the utility class is this,

send.setOnClickListener(view -> {
            Bitmap bitmap = BitmapFactory.decodeFile(filePath);

            int width = bitmap.getRowBytes();
            int height = bitmap.getHeight();
            int bmpSize = width * height;

            ByteBuffer byteBuffer = ByteBuffer.allocate(bmpSize);
            bitmap.copyPixelsToBuffer(byteBuffer);

            byte[] byteArray = byteBuffer.array();
            sendUtils.write(byteArray);

            bitmap.recycle();
    });

This is the utility class that handles the sending and receiving of data,

/**
 * 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 bluetoothsocket;
    private final InputStream inputStream;
    private final OutputStream outputStream;

    public ConnectedThread(BluetoothSocket socket) {
        bluetoothsocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        try {
            tmpIn = bluetoothsocket.getInputStream();
            tmpOut = bluetoothsocket.getOutputStream();
        } catch (IOException e) {
            Log.e("ConnectedThrd->Cons", "Socket not created.");
            e.printStackTrace();
        }
        inputStream = tmpIn;
        outputStream = tmpOut;
    }

    public void run() {
        byte[] buffer = new byte[8192]; //1024 original
        int bytes;

        // Keep listening to the InputStream while connected
        while (true) {
            try {
                // Read from the InputStream
                try {
                    bytes = inputStream.read(buffer);
                    // Send the obtained bytes to the UI Activity
                    handler.obtainMessage(BluetoothSend.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
                    handler.obtainMessage(BluetoothReceive.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
                } catch (NullPointerException n) {
                    Log.e("ConnectedThrd->Run", n.getMessage());
                }
            } catch (IOException e) {
                Log.e("ConnectedThrd->Run", "Connection Lost.", e);
                e.printStackTrace();
                connectionLost();
                break;
            }
        }
    }

    public void write(byte[] buffer) {
        try {
            try {
                outputStream.write(buffer);
                handler.obtainMessage(BluetoothSend.MESSAGE_WRITE, -1, -1, buffer)
                        .sendToTarget();
                handler.obtainMessage(BluetoothReceive.MESSAGE_WRITE, -1, -1, buffer)
                        .sendToTarget();
            } catch (NullPointerException n) {
                Log.e("ConnectedThrd->Write", "Bluetooth Socket is null: " + n.getMessage());
            }
        } catch (IOException e) {
            Log.e("ConnectedThread->Write", "Empty write stream.");
        }
    }

    public void cancel() {
        try {
            bluetoothsocket.close();
        } catch (IOException e) {
            Log.e("ConnectedThread->Cancel", "Failed to close socket.");
        }
    }
}

Lastly, on the BluetoothReceive class, I receive the data using a handler. Code for handler object is as follows,

            case MESSAGE_READ:
                //Read message from sender
                byte[] bufferRead = (byte[]) message.obj;
                //bitmap decodedByte is null
                Bitmap decodedByte = BitmapFactory.decodeByteArray(bufferRead, 0, bufferRead.length);
                int height = decodedByte.getHeight();
                int width = decodedByte.getWidth();

                Bitmap.Config config = Bitmap.Config.valueOf(decodedByte.getConfig().name());
                Bitmap bitmap_tmp = Bitmap.createBitmap(width, height, config);
                ByteBuffer buffer = ByteBuffer.wrap(bufferRead);
                bitmap_tmp.copyPixelsFromBuffer(buffer);
                fileView.setImageBitmap(bitmap_tmp);
                break;

I seem to always get a null value when I try to convert the byte array received from the other device when I convert it to a bitmap so I can use it to display it in an ImageView.

What am I doing wrong?

As you said, you can pass strings. You can convert bitmap to Base64 string format and sent it.

Bitmap bitmap = BitmapFactory.decodeFile("filePath");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); 
byte[] bytes = baos.toByteArray();
String encodedImage = Base64.encodeToString(bytes, Base64.DEFAULT);

On receiving side, reverse it (String Base64 to image)

byte[] decodedString = Base64.decode(encodedImage, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM