Send a string message continously with delay via Bluetooth

424 views Asked by At

I'm struggling with some problem with my Bluetooth App. The App is connected to the OBD2 interface via Bluetooth and my goal is to receive some data from my car like Speed, RPM etc. I made an app which has a button And when I click it I send a message to OBD2 interface and I get response. But my goal is to receive this data continuously. So I figured out that I can do that inside the onResume() method. Below is simple code that sends message.

@Override
protected void onResume() {
    super.onResume();

    HandlerDelay.postDelayed(new Runnable() {
        @Override
        public void run() {
            checkSPDstatus();

        }
    },500);
}

private void checkSPDstatus(){

    if (mmSocket != null){

        try {
            mmSocket.getOutputStream().write("010C\r".getBytes());
        } catch (IOException e) {

            Log.e("Status", String.valueOf(e));
        }

    }
}

But using that my app crashes and can't even connect with BT device.. To connect my app via BT Im using AsyncTask. I will be grateful for any help.

Regards Matt.

1

There are 1 answers

0
Matt199 On

Ok I figured out how to do that. I used Service to connect with Bluetooth Device instead AsyncTask. I used two Handlers. Now everything works. I can send String message in every 500ms and also I can get response from OBD2 Interface. Below is code for Service Class. I used BroadcastReceiver to receive data from Service to my UI.

public class BTConnect extends Service {

    private BluetoothAdapter btAdapter;
    private String adress;
    private static UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private BluetoothSocket mmSocket;
    private boolean isBTConnected = false;
    private ConnectedThread mConncetedThread;
    Handler h;
    Handler HandlerDelay = new Handler();
    final int handlerState = 0;
    public StringBuilder recDataString = new StringBuilder();
    private Timer mTimer;
    final static String MY_ACTION = "MY_ACTION";


    public BTConnect() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }


    @Override
    public void onCreate() {
        super.onCreate();

        if(mTimer != null) {

            mTimer.cancel();

        } else {

            mTimer = new Timer();
        }

        mTimer.scheduleAtFixedRate(new TimerDisplay(), 0, 500);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        String adressMac = intent.getStringExtra("MAC_ADRESS");

        // Trzeba sie połączyć

        h = new MyHandler();

        tryToConnect(adressMac);

        return START_NOT_STICKY;
    }



    private void tryToConnect(String address) {

        try {
            if (mmSocket == null || !isBTConnected) {

                btAdapter = BluetoothAdapter.getDefaultAdapter();

                BluetoothDevice device = btAdapter.getRemoteDevice(address);

                mmSocket = device.createInsecureRfcommSocketToServiceRecord(myUUID);

                BluetoothAdapter.getDefaultAdapter().cancelDiscovery();

                mmSocket.connect();

                isBTConnected = true;

                mConncetedThread = new ConnectedThread(mmSocket);
                mConncetedThread.start();


            }


        } catch (IOException e) {

            Log.e("Error", String.valueOf(e));

        }

            if (isBTConnected) {

                Log.d("Status", "Connected");
                Toast.makeText(getBaseContext(), "Connected", Toast.LENGTH_LONG);

            }

    }


    private class ConnectedThread extends Thread {

        private final InputStream mmInStream;
        private final OutputStream mmOutStream;


        public ConnectedThread(BluetoothSocket  socket) {

            mmSocket = socket;

            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();

            } catch (IOException e) {

                e.printStackTrace();
            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;

        }

        @Override
        public void run() {
            super.run();

            byte[] mmBuffer = new byte[1024];

            int mmBytes;


            //Start Listening

            while(true) {

                try {
                    mmBytes = mmInStream.read(mmBuffer);

                    Message readMsg = h.obtainMessage(handlerState, mmBytes, -1, mmBuffer);
                    readMsg.sendToTarget();


                } catch (IOException e){

                    e.printStackTrace();
                    Toast.makeText(getBaseContext(), "Input stream was disconnected", Toast.LENGTH_LONG).show();
                    break;

                }

            }
        }

        public void write(){

            try {
                mmSocket.getOutputStream().write("010C\r".getBytes());
            } catch (IOException e) {
                Log.e("Error", String.valueOf(e));
            }
        }
    }


    private class MyHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            if (msg.what == handlerState) {

                Intent sendIntent = new Intent();

                byte[] rBuff = (byte[]) msg.obj; // recived message (bytes)

                String readMessage = new String(rBuff, 0, msg.arg1); // convert that message to string

                recDataString.append(readMessage);

                Log.d("Tab", String.valueOf(recDataString));

                int startOfIndex = recDataString.indexOf("41 0C");
                int stopIndex = recDataString.indexOf(">");

                if (stopIndex > 0) {

                    Log.d("RedVal", String.valueOf(recDataString));
                    String msg1 = String.valueOf(recDataString);

                    sendIntent.putExtra("SEND_MESSAGE", msg1);
                    sendIntent.setAction(MY_ACTION);
                    sendBroadcast(sendIntent);


                    recDataString.delete(0, recDataString.length());


                } else if(recDataString.length() > 33) {



                    String msg1 = String.valueOf(recDataString.substring(recDataString.length()-26, recDataString.length()));
                    sendIntent.putExtra("SEND_MESSAGE", msg1);
                    sendIntent.setAction(MY_ACTION);
                    sendBroadcast(sendIntent);
                    recDataString.delete(0, recDataString.length());
                }




            }

        }
    }

    class TimerDisplay extends TimerTask {

        @Override
        public void run() {
            HandlerDelay.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mConncetedThread.write();
                }
            },500);
        }
    }




}