0

I'm making a OBDII Bluetooth Android app and i'm having some issues sending out commands. I've already made a successfully connection between my mobile device and my OBDII adapter, but when I click on another activity, the Bluetooth connection seems to quit?

When you open up the app you'll see a button that says "Connect Device". When you press that, a ListAdapter will show up with paired Bluetooth devices. Then when you have succesfully connected to the device (OBDII Adapter) it will take you to another layout where there is 3 activities that are 3 different powerplatforms for cars. This is where the problem occurs. For now, I just want to be able to read the voltage from the OBDII. But when I click my button getValue inside one of the 3 activities. I get an logcat error. And I think it's because I haven't initiated my BluetoothHandler properly. I have no idea how to do this.

MainActivity:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    Button b1;
    BluetoothAdapter mAdapter;
    FragmentHostCallback mHost;
    BTHandler btHandler;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case Constants.MESSAGE_STATE_CHANGE:
                    switch (msg.arg1) {
                        case BTHandler.STATE_CONNECTED:
                            //setContentView(R.layout.activity_connected);
                            Intent intent = new Intent(MainActivity.this, Connected.class);
                            startActivity(intent);
                            Toast.makeText(getApplicationContext(), R.string.title_connected_to, Toast.LENGTH_SHORT).show();
                            Log.v("Log", "Connected");
                            break;
                        case BTHandler.STATE_NONE:
                            Toast.makeText(getApplicationContext(), R.string.title_not_connected, Toast.LENGTH_SHORT).show();
                            break;
                    }
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btHandler = new BTHandler(MainActivity.this, mHandler);
        b1 = (Button) findViewById(R.id.connect);
        b1.setOnClickListener(this);
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        //init();

        if (mAdapter == null) {
            Toast.makeText(getApplicationContext(), R.string.device_not_supported, Toast.LENGTH_LONG).show();
            finish();
        } else {
            if (!mAdapter.isEnabled()) {
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(intent, 1);
            }
        }
        //BTHandler btHandler = new BTHandler(MainActivity.this, mHandler);
        //btHandler.connect("");
    }

    public void onClick(View v) {
        int id = v.getId();
        //String voltage = ("ATRV");

        switch (id) {
            case R.id.connect:
                onConnect(); //Operation
                Log.v("Log", "Pressed onClick");
                break;
            /*case R.id.getValue:
                btHandler.write(voltage);
                Log.v("Log", "getValue" + voltage);
                break;*/
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_CANCELED) {
            Toast.makeText(getApplicationContext(), R.string.enable_bluetooth, Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    private void onConnect() {
        ArrayList deviceStrs = new ArrayList();
        final ArrayList<String> devices = new ArrayList();

        BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
        Set pairedDevices = mAdapter.getBondedDevices();
        if (pairedDevices.size() > 0) {
            for (Object device : pairedDevices) {
                BluetoothDevice bdevice = (BluetoothDevice) device;
                deviceStrs.add(bdevice.getName() + "\n" + bdevice.getAddress());
                devices.add(bdevice.getAddress());
            }
        }

        // show list
        final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);

        ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.select_dialog_singlechoice,
                deviceStrs.toArray(new String[deviceStrs.size()]));

        alertDialog.setSingleChoiceItems(adapter, -1, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                int position = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
                String deviceAddress = devices.get(position);

                btHandler.connect(deviceAddress);
                //btHandler.write();

            }
        });
        alertDialog.setTitle("Paired devices");
        alertDialog.show();
    }

BTHandler:

public class BTHandler {

    public static final int STATE_NONE = 0;       // we're doing nothing
    public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
    public static final int STATE_CONNECTED = 3;  // now connected to a remote device

    final ArrayList<String> devices = new ArrayList();
    private final Handler mHandler;
    private BluetoothAdapter mAdapter;
    private BluetoothDevice device;
    private ConnectThread mConnectThread;
    private ConnectedThread mConnectedThread;
    private BluetoothSocket socket;
    private String status;
    private int mState;
    private boolean connectionStatus = false;

    public BTHandler(Context context, Handler handler) { // Konstruktor
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mHandler = handler;
    }

    public void write(String s) {
        mConnectedThread.sendRawCommand(s);
        Log.v("write", "write");
    }

    /*
    public void write(byte[] bytes) {
        try {
            mmOutStream.write(bytes);
        } catch (IOException e) {
        }
    }
    */
    public void connect(String deviceAddress) {
        mConnectThread = new ConnectThread(deviceAddress);
        mConnectThread.start();
    }

    private void guiHandler(int what, int arg1, String obj) {
        Message msg = mHandler.obtainMessage();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.sendToTarget();
    }

    private class ConnectThread extends Thread {
        BluetoothSocket tmp = null;
        private BluetoothSocket mmSocket;

        public ConnectThread(String deviceAddress) {
            mAdapter = BluetoothAdapter.getDefaultAdapter();
            device = mAdapter.getRemoteDevice(deviceAddress);

            BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
            BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
            UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
            try {
                tmp = device.createRfcommSocketToServiceRecord(uuid);
                //socket.connect();
                //Log.v("connect", "connect");
            } catch (IOException e) {
                //e.printStackTrace();
                //Log.v("exception", "e");
            }
            mmSocket = tmp;
        }

        public void run() {
            // Cancel discovery because it will slow down the connection
            mAdapter.cancelDiscovery();
            byte[] buffer = new byte[1024]; // buffer store for the stream
            int bytes;

            try {
                // Connect the device through the socket. This will block
                // until it succeeds or throws an exception
                mmSocket.connect();
                Log.v("connect", "connect");
            } catch (IOException connectException) {
                // Unable to connect; close the socket and get out
                try {
                    mmSocket.close();
                    Log.v("close", "close");
                } catch (IOException closeException) {
                }
                guiHandler(Constants.TOAST, Constants.SHORT, "Connection Failed");
                return;
            }
            guiHandler(Constants.CONNECTION_STATUS, Constants.STATE_CONNECTED, "");
            mConnectedThread = new ConnectedThread(mmSocket);
            mConnectedThread.start();
        }
    }

    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;
        private ObdMultiCommand multiCommand;

        public ConnectedThread(BluetoothSocket socket) {
            connectionStatus = true;
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;

            try {
                //RPMCommand engineRpmCommand = new RPMCommand();
                //SpeedCommand speedCommand = new SpeedCommand();
                ModuleVoltageCommand voltageCommand = new ModuleVoltageCommand();

                while (!Thread.currentThread().isInterrupted()) {
                    //engineRpmCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
                    //speedCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
                    voltageCommand.run(socket.getInputStream(), socket.getOutputStream());
                    // TODO handle commands result
                    //Log.d("Log", "RPM: " + engineRpmCommand.getFormattedResult());
                    //Log.d("Log", "Speed: " + speedCommand.getFormattedResult());
                    Log.v("Log", "Voltage: " + voltageCommand.getFormattedResult());
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

        public void run() {
            byte[] buffer = new byte[1024];  // buffer store for the stream
            int bytes; // bytes returned from read()

            OBDcmds();
            // Keep listening to the InputStream until an exception occurs
            while (connectionStatus) {
                sendMultiCommand();
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        // CALL this to MainActivity
        public void sendRawCommand(String command) {
            try {
                new OdbRawCommand(command);

            } catch (Exception e) {
                Log.v("sendRawCommand", "e");
            }
        }

        private void OBDcmds() { // execute commands

            try {
                new EchoOffCommand().run(socket.getInputStream(), socket.getOutputStream());
                new LineFeedOffCommand().run(socket.getInputStream(), socket.getOutputStream());
                new TimeoutCommand(100).run(socket.getInputStream(), socket.getOutputStream());
                new SelectProtocolCommand(ObdProtocols.AUTO).run(socket.getInputStream(), socket.getOutputStream()); //ISO_15765_4_CAN

            } catch (Exception e) {
                Log.v("OBDcmds", "e");
                // handle errors
            }
        }
        /*
        // Call this from the main activity to send data to the remote device
        public void write(byte[] bytes) {
            try {
                mmOutStream.write(bytes);
            } catch (IOException e) {
            }
        }
        */

        /* Call this from the main activity to shutdown the connection */
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
            }
        }

        public void sendMultiCommand() {
            try {
                // RUN some code here
            } catch (Exception e) {
            }
        }
    }
}

SPA: One of the power platforms mentioned before.

public class SPA extends AppCompatActivity implements View.OnClickListener {
    Button b2;
    BTHandler btHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sp);
        b2 = (Button) findViewById(R.id.getValue);
        b2.setOnClickListener(this);
    }

    public void onClick(View v) {
        int id = v.getId();
        String voltage = ("AT RV");

        switch (id) {
            case R.id.getValue:
                btHandler.write(voltage);
                Log.v("Log", "getValue" + voltage);
                break;
        }
    }
}

Logcat:

enter image description here

swess
  • 171
  • 19

1 Answers1

0

The reason of the error is here:

BTHandler btHandler;

and you are doing this:

btHandler.write(voltage);

but the object is null referenced....

you need to initialize the BTHandler in the oncreate...
or maybe better:

use a service so you can Bind all the activities to that...

PS:

Note that the BTHandler of the MainActivity is not the same as the one declared in the SPA Class... so although that btHandler is constructed and works in MainActivity doesnt mean it will work in other activities/classes

Community
  • 1
  • 1
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
  • I've updated the post to show the `write` method. It's weird that it's null when I have `new OdbRawCommand(command);` (I'm using the obdii api btw). Maybe you could show me how I would go about? – swess Mar 23 '16 at 15:18
  • Could you show how I would initialize the BTHandler in onCreate? – swess Mar 24 '16 at 07:47