5

I am writing an application that needs to exchange data with a Bluetooth 2.1 device. I have done it several times but this time something weird is happening.

    Log.d("TAG", "connectToDevice");

    if(macAddress != null)
        deviceToConnect = mBluetoothAdapter.getRemoteDevice(macAddress);

    Log.d("TAG", "macAddress != null");


    if(deviceToConnect != null)
        try {
            btSocket = deviceToConnect.createRfcommSocketToServiceRecord(UUID.fromString(SharedIncludes.SPP_UUID));
        } catch (IOException e) {
            btSocket = null;
            e.printStackTrace();
        }

    Log.d("TAG", "deviceToConnect != null");

    if(btSocket != null){

        try {
            inputStream = btSocket.getInputStream();
            Log.d("TAG", "inputStream OK");

        } catch (IOException e) {
            inputStream = null;
            Log.d("TAG", "inputStream KO");
            e.printStackTrace();
        }

        try {
            outputStream =  btSocket.getOutputStream();
            Log.d("TAG", "outputStream OK");

        } catch (IOException e) {
            outputStream = null;
            Log.d("TAG", "outputStream KO");
            e.printStackTrace();
        }

    }


    Log.d("TAG", "btSocket != null");
    Log.d("TAG", "onConnectionEstablished");

After the discovering phase I get the BluetoothDevice I need to connect to and then I obtain the socket, input & output streams.

I then have a thread that reads from the input stream.

   int byteRead;

    while (listening) {
        try {
            if(inputStream!=null){
                Log.d("TAG", "inputStream: " +inputStream);
                byteRead = inputStream.read();
            }else{
                Log.d("TAG", "inputStream is null!");
                continue;
            } // Rest of the code here

I get this error while executing the inputStream.read() line:

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.read(byte[], int, int)' on a null object reference

at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:427)
at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:60)
at com.me.testapplication.Connection_BT21.run(Connection_BT21.java:152)

Problem 1: why NullPointerException if I am checking that inputStream != null?

Problem 2: why read(byte[], int, int) if I am trying to call read()?

The Good Giant
  • 1,740
  • 2
  • 19
  • 35
  • Problem 2: Because internally the read() calls read(byte[], int, int). Notice the 2 steps inside the android framework above your call Problem 1: This isn't throwing an exception inside your code, its throwing it inside the framework. So it isn't your input stream that's null, its an inputStream inside of your inputStream which Android is trying to call. So the null means either a framework bug or that something is in a bad state in the bluetooth socket. – Gabe Sechan Jun 17 '14 at 15:29
  • What is line 152 of Connection_BT21.java? – Husman Jun 17 '14 at 15:33
  • @Husman: line 152 is inputStream.read() – The Good Giant Jun 17 '14 at 15:34
  • @Gabe: Ok it was my guess too, but do you think it could be related to the socket or maybe to the android apis I'm using? – The Good Giant Jun 17 '14 at 15:35
  • 1
    Where do you initialise the inputStream? It may not be null but it may not be in a state where it is ready to read(), or the underlying stream may not be ready. – Husman Jun 17 '14 at 15:42
  • The line where I initialise it is inthe first snippet "inputStream = btSocket.getInputStream()". It was not ready.. because I simply did not connect() to the socket :D – The Good Giant Jun 17 '14 at 16:49

2 Answers2

8

I found the error, you were all right: there was an error with the socket.. I needed to call socket.connect()!

if(macAddress != null)
    deviceToConnect = mBluetoothAdapter.getRemoteDevice(macAddress);

Log.d("TAG", "macAddress != null");


if(deviceToConnect != null)
    try {
        btSocket = deviceToConnect.createRfcommSocketToServiceRecord(UUID.fromString(SharedIncludes.SPP_UUID));
    } catch (IOException e) {
        btSocket = null;
        e.printStackTrace();
    }

Log.d("TAG", "deviceToConnect != null");

if(btSocket != null){
 //This was the line missing!
 btSocket.connect();

    try {
        inputStream = btSocket.getInputStream();
        Log.d("TAG", "inputStream OK");

    } catch (IOException e) {
        inputStream = null;
        Log.d("TAG", "inputStream KO");
        e.printStackTrace();
    }

    try {
        outputStream =  btSocket.getOutputStream();
        Log.d("TAG", "outputStream OK");

    } catch (IOException e) {
        outputStream = null;
        Log.d("TAG", "outputStream KO");
        e.printStackTrace();
    }

}

That was why the inputStream was not ready and I got that error.

Sorry, I just didn't see it.. Hope it can help someone!

The Good Giant
  • 1,740
  • 2
  • 19
  • 35
0

Problem 1: why NullPointerException if I am checking that inputStream != null?

Your getting a NullPointerException, not because your inputStream is null, your InputStream is fine; However there is an InputStream either in BluetoothSocket.java or BluetoothInputStream.java, that is null and a read method is being called on that.

Problem 2: why read(byte[], int, int) if I am trying to call read()?

relates to problem one. int java.io.InputStream.read(byte[], int, int) is being called in one of your other files, on a null InputStream.

Husman
  • 6,819
  • 9
  • 29
  • 47
  • Ok, it was my guess to but thanks for having confirmed it to me. Which can be the reason? the only reason I can imagine is something related to the socket.. – The Good Giant Jun 17 '14 at 15:37