javaandroidstringobd-ii

Send a string to OBD-II


I want to send a String to an OBD-II adapter, to read some information, for example the battery voltage. So I wrote this little program:

public class MainActivity extends Activity {
    private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter
            .getDefaultAdapter();
    private ConnectedThread connected;
    private boolean isConnected = false;

    //private final BluetoothSocket mmSocket;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // Button ruft die Methode verbindung auf!!!!
    public void verbinden(View view) {
        verbindung();
        Toast.makeText(getApplicationContext(), "Verbunden!", Toast.LENGTH_LONG).show();
    }

    // Senden Button
    public void senden(View view) {
        String message;
        EditText Message = (EditText) findViewById(R.id.TFKonsole);
        message = (Message.getText().toString());
        Toast.makeText(getApplicationContext(), "Nachricht gesendet!", Toast.LENGTH_LONG).show();

        for (int i = 0; i < message.length(); i++) {
            char c = message.charAt(i);
            String bereit = Integer.toHexString(c);
            System.out.println(bereit);
            byte[] send = bereit.getBytes();
            connected.write(send);
            //connected.write(abschluss);
        }
    }

    // Trennen Butto
    public void trennen(View view) {
        connected.cancel();
    }

    // Verbindung wird ausgeführt
    private void verbindung() {
        String address = "AA:BB:CC:11:22:33"; // Adresse vom Dongle(ITEM)
                                              // 00:0D:18:06:00:00 ADRESSE VOM
                                              // DONGEL (ANDREAS)
                                              // 00:0D:18:3A:67:89
                                              // B8:E8:56:41:74:09marco
                                              // 00:09:DD:42:5B:AA adresse
                                              // bluetoothstick

        BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
        ConnectThread connect = new ConnectThread(device);
        connect.start();
        //connected.write(null);
    }

    private class ConnectThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;

        public ConnectThread(BluetoothDevice device) {

            //mBluetoothAdapter.cancelDiscovery();
            // Use a temporary object that is later assigned to mmSocket,
            // because mmSocket is final
            BluetoothSocket tmp = null;
            mmDevice = device;
            ParcelUuid[] i = device.getUuids();

            // Holt sich ein BluetoothSocket, um sich mit dem BluetoothDevice zu
            // verbinden
            try {
                // MY_UUID is the app's UUID string, also used by the server
                // code
                Method m = device.getClass().getMethod("createRfcommSocket",
                        new Class[] { int.class });
                tmp = (BluetoothSocket) m.invoke(device, 1);
            } 
            catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
            } 
            catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
            } 
            catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            mmSocket = tmp;
        }

        public void run() {
            // Trenne die Verbindung, weil eine bestehende Verbindung viel
            // Speicher in anspruch nimmt
            // mBluetoothAdapter.cancelDiscovery();

            try {
                mBluetoothAdapter.cancelDiscovery();
                // Verbinde das Gerät über den Socket. Dies wird geblockt,
                // bis die Verbindung erfolgt oder eine Exception fliegt
                mmSocket.connect();
                isConnected = true;
                boolean k = mmSocket.isConnected();
                System.out.println(k + " Verbindung erfolgreich");
            } 
            catch (IOException connectException) {
                connectException.printStackTrace();
                // Verbinden unmöglich; Schließe den Socket und beende die App
                boolean a = mmSocket.isConnected();
                System.out.println(a + " Verbindung fehlgeschlagen a");
                try {
                    mmSocket.close();
                } 
                catch (IOException closeException) {
                    boolean b = mmSocket.isConnected();
                    System.out.println(b + " Verbindung fehlgeschlagen b");
                }
                return;
            }

            connected = new ConnectedThread(mmSocket);
            connected.run();
        }

        // Will cancel an in-progress connection, and close the socket
        public void cancel() {
            try {
                mmSocket.close();
            } 
            catch (IOException e) {
            }
        }
    }

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

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

            // Get the input and output streams, using temp objects because
            // member streams are final
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } 
            catch (IOException e) {
                e.printStackTrace();
            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        public void run() {
            byte[] buffer = new byte[1024]; // Buffer store für den Stream
            int bytes; // bytes, die von read() zurückgegeben werden

            // Achte auf den InputStream, bis alles übertragen wurde
            // oder eine Exception fliegt
            while (true) {
                try {
                    // Lese von dem InputStream
                    bytes = mmInStream.read(buffer);
                    // Send the obtained bytes to the UI activity
                    // mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
                    // .sendToTarget();

                    // Ausgabe im Textfeld
                    // setContentView(R.layout.activity_main);
                    final String sausgabe = new String(buffer);
                    final TextView ausgabe = (TextView) findViewById(R.id.textView1);

                    runOnUiThread(new Runnable() {

                        // Methode, um einen Thread aus einem anderen aufzurufen
                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            ausgabe.setText("\n" + sausgabe);
                            Log.e("", "Aufruf");
                        }
                        // Do something on UI thread Update UI
                    });

                } 
                catch (IOException e) {
                    break;
                }
            }
        }

        // Rufen sie diese Methode auf, um Daten zum Remote Gerät zu senden
        public void write(byte[] bytes) {
            try {
                mmOutStream.write(bytes);
                //connected.write(null);
            } 
            catch (IOException e) {
                e.printStackTrace();
                System.out.println("Senden fehlgeschlagen");
            }
        }

        // Rufen sie diese Methode auf, um die Verbindung zu trennen
        public void cancel() {
            try {
                Toast.makeText(getApplicationContext(), "Getrennt!", Toast.LENGTH_LONG).show();
                mmSocket.close();
                System.out.println("Getrennt");
            } 
            catch (IOException e) {
                System.out.println("Trennen fehlgeschlagen");
            }
        }
    }
}

Layout

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.blue_final.MainActivity$PlaceholderFragment" >

    <Button
        android:id="@+id/BtnVerbinden"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:onClick="verbinden"
        android:text="verbinden" />

    <EditText
        android:id="@+id/TFKonsole"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/BtnVerbinden"
        android:layout_alignRight="@+id/BtnSenden"
        android:layout_below="@+id/BtnVerbinden"
        android:ems="10" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/BtnVerbinden"
        android:layout_alignBottom="@+id/BtnVerbinden"
        android:layout_alignParentRight="true"
        android:onClick="trennen"
        android:text="@string/gui_trennen" />

    <Button
        android:id="@+id/BtnSenden"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/TFKonsole"
        android:layout_toLeftOf="@+id/button1"
        android:onClick="senden"
        android:text="senden" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignRight="@+id/button1"
        android:layout_below="@+id/TFKonsole" />

</RelativeLayout>

If I press the Send button, I get a ? (question mark). I think it’s something wrong with my for loop. The dongle only reads hexadecimal numbers, but I can only send bytes.


Solution

  • I think you have a problem in your for loop:

    for (int i = 0; i < message.length(); i++) {
        char c = message.charAt(i);
        String bereit = Integer.toHexString(c);
        System.out.println(bereit);
        byte[] send = bereit.getBytes();
        connected.write(send);
        //connected.write(abschluss);
    }
    

    You're sending the entire message for each of the message positions.