
Why is it necessary for your car?
Have you ever thought about displaying the parameters of your car in your own Android application? If yes, then welcome under cat. We will discuss the development of such an application.
First, let's take a look at the protocols used to diagnose vehicles.
OBD is an abbreviation for on-board diagnostics and refers to self-diagnostics and vehicle reporting tools. The original protocol is intended to speed up the process of diagnostics by service personnel. The first versions allowed to diagnose some problems in the engine. Now, in addition to the diagnostic capabilities, other features are added, such as obtaining different information, such as current fuel consumption, controlling various components, such as automatic transmission, transmission mode, obtaining GPS coordinates, and more. Learn in more detail how this works and the story you can in
Wikipedia .
Necessary materials

First of all, we need an OBDII adapter capable of working with your car. There are many such adapters. Some of them have a COM interface, some have a USB interface, and some have a Bluetooth interface. Theoretically, anyone can be used for our application, but in practice, the best option is still Bluetooth. Also, adapters may be different supported OBDII protocols (ie, actually supported cars). So if you have a car and a suitable OBDII adapter at hand, we can start developing our application.
Wait - do you really have a car close enough to the development environment? In fact, we could use the simulator at first. One of the options that works for me is the OBDSim application. This is an open source project available for many platforms. But since Bluetooth is not supported in Windows, the application will need to be assembled from source codes in Linux. Also note that most likely you will need to make changes to the source code in order to change the RFCOMM channel to the first available instead of the proposed channel 1.
The second option is a hardware simulator that can be used instead of a car. I used the
ECUsim 2000 standard with the ISO 15765 (CAN) protocol enabled. And I used the OBDII adapter ELM327 v.1.5

')
Application development
Let's begin by describing the protocol used for communication between an Android device and an OBDII adapter / car. This is a text polling protocol. This means that all you need is to send a command in order to get an answer. And knowing which commands you can send is key.
We will connect to the adapter via Bluetooth. It seems that the
Bluetooth Low Energy API would be a good option. But since it is supported by just a few devices, it is now too early to use it.
The protocol supports some
AT commands such as echo off and carriage return control. The second part of the protocol is the OBDII control protocol itself.
The general scheme of the application is as follows:
- connect to OBDII adapter via Bluetooth
- initialize OBDII adapter using AT commands
- continuously receive the required data from the vehicle by sending the appropriate PID codes
Connection to OBDII adapter is fairly standard. But one thing that needs to be done before connecting is choosing a Bluetooth device. Displaying the alert dialog with a list of devices is fine:
ArrayList<String> deviceStrs = new ArrayList<String>(); final ArrayList<String> devices = new ArrayList<String>(); BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); Set<BluetoothDevice> pairedDevices = btAdapter.getBondedDevices(); if (pairedDevices.size() > 0) { for (BluetoothDevice device : pairedDevices) { deviceStrs.add(device.getName() + "\n" + device.getAddress()); devices.add(device.getAddress()); } }
Do not forget to save somewhere the address of the selected device. Now we can connect to the selected device:
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); BluetoothDevice device = btAdapter.getRemoteDevice(deviceAddress); UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); BluetoothSocket socket = device.createInsecureRfcommSocketToServiceRecord(uuid); socket.connect();
The UUID in the code above represents a “serial” interface via Bluetooth. Of course, this code must be executed in a non-UI stream. I would also recommend to look
here for details and the solution to the error in Android which can lead to the impossibility of connecting in some cases.
Now we can exchange data. For this we will use the
OBD-Java-API library. The library is quite simple. It has several classes that correspond to different OBD commands. Remember to initialize the OBDII adapter by sending configuration commands:
new EchoOffObdCommand().run(socket.getInputStream(), socket.getOutputStream()); new LineFeedOffObdCommand().run(socket.getInputStream(), socket.getOutputStream()); new TimeoutObdCommand().run(socket.getInputStream(), socket.getOutputStream()); new SelectProtocolObdCommand(ObdProtocols.AUTO).run(socket.getInputStream(), socket.getOutputStream());
Now we are ready to send other commands:
EngineRPMObdCommand engineRpmCommand = new EngineRPMObdCommand(); SpeedObdCommand speedCommand = new SpeedObdCommand(); while (!Thread.currentThread().isInterrupted()) { engineRpmCommand.run(sock.getInputStream(), sock.getOutputStream()); speedCommand.run(sock.getInputStream(), sock.getOutputStream());

Here I want to note that the library has some problems with parsing and often falls due to insufficiently good error handling. The first problem is the performCalculations method, which is present in all command classes. It would be good to check the buffer size before accessing it, because in some cases the answer may be shorter than necessary. Of course, the short answer problem lies with the OBDII adapter / car, but the library should be ready for such problems.
Among other things, there are still some problems there, so this library still needs improvements or can simply be used as a source of information.
The received data can be saved somewhere for further analysis, for example in
ElasticSearch .
And now we are working on the Hours of Service app for truck drivers and continue to share experiences in our
blog . Stay tuned!
PS In fact, I am also the author of the original English version of the article, which was published on
blog.lemberg.co.uk , so I can answer technical questions.