Skip to content

Instantly share code, notes, and snippets.

@sankarganesh
Created August 29, 2013 09:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save sankarganesh/6376031 to your computer and use it in GitHub Desktop.
Save sankarganesh/6376031 to your computer and use it in GitHub Desktop.
/**
* Provides the Main Activity class and Bluetooth Socket Listener class
* <p>
* The Main Activity class deals with establishing the connection with OBDII
*
*
*/
package com.example.obddemo;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
import java.util.UUID;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckedTextView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
/**
* @author Sankar Ganesh
*
*/
public class MainActivity extends Activity {
// Declaration of Blue tooth Adapter variable
BluetoothAdapter adapterObject = null;
// Declaration of Blue tooth Device variable
BluetoothDevice btdevconnected = null;
// Declaration of Blue tooth Socket variable
BluetoothSocket btscoket = null;
/**
* Declaration of Object for Connect Thread class which performs connection
* with OBDII
*/
ConnectThread btConnectThread = null;
// File Object for recording data in and out from OBD and also logging the
// error
static File obdRetriver = null;
File obdReceiver = null;
// Object which holds the value of Context
public static Context contextObject = null;
// In & Out Stream objects declaration
OutputStream outStream = null;
InputStream inStream = null;
// A variable which holds the position of selected devices from the list of
// paried devices
int selectedPosition = 0;
// Declaration of OBD parameters ..
static String rpm;
static String speed;
static String engineAttributes;
static String engineCoolantAttributes;
static String fuelLevel;
// UI component which shows the data from OBD
public static TextView showRPM;
public static TextView showSpeed;
public static TextView showEngineAttributes;
public static TextView showEngineCoolantAttribute;
public static TextView showFuelLevel;
// UUID declaration
private static final UUID BT_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapterObject = BluetoothAdapter.getDefaultAdapter();
contextObject = MainActivity.this;
showRPM = (TextView) findViewById(R.id.rpm_param);
showSpeed = (TextView) findViewById(R.id.speed_param);
showEngineAttributes = (TextView) findViewById(R.id.engine_Load_param);
showEngineCoolantAttribute = (TextView) findViewById(R.id.engine_coolant_param);
showFuelLevel = (TextView) findViewById(R.id.fuel_level_param);
/** Check whether Blue tooth is turned on in the device or not */
if (!adapterObject.isEnabled()) {
displayAlert(
"Application is requesting permission to turn on Bluetooth. Allow?",
MainActivity.this, "BLUETOOTH", "ok", null);
} else {
ArrayList<String> devName = getListOfDevicesName();
ArrayList<String> devAddress = getListOfDevicesAddress();
/**
* Show List of Paired devices and allow the user to choose his
* desired device.
*/
if (devName != null && devName.isEmpty() == false) {
showBluetoothDialog(devName, devAddress);
} else {
// If one the devices paired , we just ask user to pair the OBD
// devices manually
// i.e., Go to Settings - > Wire less - > Blue tooth - > Scan ->
// Pair
displayErrorAlert("Please pair with the Device",
MainActivity.this);
}
}
}
/**
* Method it will return the List of Devices Address which is already
* paired.
*
* @param null
* @return ArrayList
*
*/
public final ArrayList<String> getListOfDevicesAddress() {
Set<BluetoothDevice> pairedDevices = BluetoothAdapter
.getDefaultAdapter().getBondedDevices();
ArrayList<String> devArrayList = null;
if (pairedDevices.size() > 0) {
devArrayList = new ArrayList<String>();
for (BluetoothDevice device : pairedDevices) {
devArrayList.add(device.getAddress());
}
}
return devArrayList;
}
/**
* Method it will return the List of Devices name which is already paired.
*
* @param null
* @return ArrayList
*/
public final ArrayList<String> getListOfDevicesName() {
Set<BluetoothDevice> pairedDevices = BluetoothAdapter
.getDefaultAdapter().getBondedDevices();
ArrayList<String> devArrayList = null;
if (pairedDevices.size() > 0) {
devArrayList = new ArrayList<String>();
for (BluetoothDevice device : pairedDevices) {
devArrayList.add(device.getName());
}
}
return devArrayList;
}
/**
* Shows a dialog with message we want to convey
*
* @param message
* @param ctx
* @param settingsMode
* @param okButtonText
* @param endButtonText
*/
protected final void displayAlert(String message, Context ctx,
final String settingsMode, String okButtonText, String endButtonText) {
try {
if (endButtonText == null) {
endButtonText = "cancel";
}
AlertDialog.Builder testDialog = new AlertDialog.Builder(ctx);
testDialog.setMessage(message);
testDialog.setNegativeButton(endButtonText,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int arg1) {
}
});
testDialog.setPositiveButton(okButtonText,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int arg1) {
try {
if (settingsMode.equalsIgnoreCase("BLUETOOTH")) {
adapterObject.enable();
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
testDialog.setCancelable(true);
testDialog.show();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Shows a dialog with Error Messages
*
* @param message
* @param ctx
*/
protected final void displayErrorAlert(String message, Context ctx) {
try {
AlertDialog.Builder errorDialog = new AlertDialog.Builder(ctx);
errorDialog.setMessage(message);
errorDialog.setPositiveButton("ok",
new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog,
int arg1) {
dialog.dismiss();
}
});
errorDialog.setCancelable(true);
errorDialog.show();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* A dialog which shows the List of Devices and enables the user to choose a
* device
*
* @param devName
* @param devAddress
*/
private void showBluetoothDialog(ArrayList<String> devName,
final ArrayList<String> devAddress) {
try {
final Dialog testBluetoothDevicedialog = new Dialog(
MainActivity.this);
testBluetoothDevicedialog
.setTitle("Select an OBD Bluetooth Adapter");
testBluetoothDevicedialog.setContentView(R.layout.deviceshow);
testBluetoothDevicedialog.setCanceledOnTouchOutside(false);
testBluetoothDevicedialog.setCancelable(false);
testBluetoothDevicedialog.show();
final ListView deviceListView;
ArrayAdapter<String> deviceArrayAdapter;
Button ok = null;
Button cancel = null;
deviceListView = (ListView) testBluetoothDevicedialog
.findViewById(R.id.devicelist);
ok = (Button) testBluetoothDevicedialog.findViewById(R.id.ok);
cancel = (Button) testBluetoothDevicedialog
.findViewById(R.id.cancel);
getWindow().setBackgroundDrawable(new ColorDrawable(0));
deviceArrayAdapter = new ArrayAdapter<String>(
getApplicationContext(), R.layout.listviewelements,
R.id.devname, devName);
deviceListView.setAdapter(deviceArrayAdapter);
deviceListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(final AdapterView<?> arg0, View view,
final int position, long itemId) {
CheckedTextView textView = (CheckedTextView) view;
for (int i = 0; i < deviceListView.getCount(); i++) {
textView = (CheckedTextView) deviceListView
.getChildAt(i);
if (textView != null) {
textView.setTextColor(Color.BLACK);
}
}
deviceListView.invalidate();
textView = (CheckedTextView) view;
if (textView != null) {
textView.setTextColor(Color.BLUE);
}
selectedPosition = position;
}
});
cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
testBluetoothDevicedialog.cancel();
}
});
ok.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
testBluetoothDevicedialog.cancel();
/**
* trying to connect with a selected devices
*
*/
btdevconnected = adapterObject.getRemoteDevice(devAddress
.get(selectedPosition));
Log.d("Clicked Device", btdevconnected.getName());
/**
* Check the discovery status , if it is in discovery mode ,
* then cancel the discovery
*
*/
if (bluetoothDiscoveringStatus()) {
cancelBluetoothDiscovery();
}
/**
* Invoke a Async Class to establish the communication with
* OBD devices
*
*/
new BluetoothAsyncClass().execute();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean bluetoothDiscoveringStatus() {
return BluetoothAdapter.getDefaultAdapter().isDiscovering();
}
public boolean cancelBluetoothDiscovery() {
return BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
}
public class BluetoothAsyncClass extends AsyncTask<Void, Void, Integer> {
ProgressDialog dialog;
/**
* Display a progress dialog
*/
protected void onPreExecute() {
dialog = new ProgressDialog(MainActivity.this);
dialog.setTitle("Trying to connect OBD Device ...");
dialog.show();
}
/**
* Run the Thread to establish the connection
*/
@Override
protected Integer doInBackground(Void... arg0) {
// Call Connect Thread ...
btConnectThread = new ConnectThread(btdevconnected, btscoket,
BT_UUID, adapterObject);
btConnectThread.run();
dialog.dismiss();
if (btConnectThread.getStatus()) {
return Integer.valueOf(1);
} else {
return Integer.valueOf(0);
}
}
protected void onPostExecute(Integer paramInteger) {
/**
* If Status is 1 , then it means that we are successfully connected
* to OBD
*/
if (paramInteger.intValue() == 1) {
displayErrorAlert(
"OBD Connected On: " + btdevconnected.getName(),
MainActivity.this);
// Start OBD to send commands
startOBDCommunicator(btConnectThread.getSocket(),
"com.example.obddemo.MainActivity$MessageSender",
"getOBDdata");
return;
} else {
/**
* A problem occurred to connect with OBD
*/
displayErrorAlert(
"ELM327 Not Found On: " + btdevconnected.getName(),
MainActivity.this);
}
}
}
public void intializeFile() {
try {
obdRetriver = new File("/sdcard/test/ObdDataLogger.txt");
obdRetriver.createNewFile();
FileOutputStream obdLoggerObject = new FileOutputStream(obdRetriver);
OutputStreamWriter obdLoggerWriter = new OutputStreamWriter(
obdLoggerObject);
obdLoggerWriter.append("OBD Logger Entry");
obdLoggerWriter.close();
obdLoggerObject.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
obdReceiver = new File("/sdcard/test/ObdReceiverLogger.txt");
obdReceiver.createNewFile();
FileOutputStream obdLoggerObject = new FileOutputStream(obdReceiver);
OutputStreamWriter obdLoggerWriter = new OutputStreamWriter(
obdLoggerObject);
obdLoggerWriter.append("OBD Logger Entry");
obdLoggerWriter.close();
obdLoggerObject.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendDataToOBD(BluetoothSocket btSocketConnected,
String paramString) {
try {
outStream = btSocketConnected.getOutputStream();
byte[] arrayOfBytes = paramString.getBytes();
try {
intializeFile();
this.outStream.write(arrayOfBytes);
FileWriter fWriter;
try {
fWriter = new FileWriter(obdRetriver, true);
fWriter.append("\r\n");
fWriter.write("Send Data to OBD");
fWriter.append("\r\n");
fWriter.write(paramString);
fWriter.flush();
fWriter.close();
} catch (Exception fileObjectException) {
fileObjectException.printStackTrace();
}
return;
} catch (IOException localIOException2) {
localIOException2.printStackTrace();
}
} catch (Exception localIOException1) {
localIOException1.printStackTrace();
}
}
public String readDataFromOBD(BluetoothSocket btSocketConnected) {
while (true) {
try {
inStream = btSocketConnected.getInputStream();
String str1 = "";
char c = (char) inStream.read();
str1 = str1 + c;
if (c == '>') {
String datafromOBD = str1.substring(0, -2 + str1.length())
.replaceAll(" ", "").trim();
intializeFile();
FileWriter fWriter;
try {
fWriter = new FileWriter(obdReceiver, true);
fWriter.append("\r\n");
fWriter.write("Read Data from OBD");
fWriter.append("\r\n");
fWriter.write(datafromOBD);
fWriter.flush();
fWriter.close();
} catch (Exception fileObjectException) {
fileObjectException.printStackTrace();
}
return datafromOBD;
}
} catch (IOException localIOException) {
return localIOException.toString();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public HashMap<String, String> startOBDCommunicator(
BluetoothSocket btSocketConnected, String paramClassName,
String methodName) {
HashMap<String, String> dataRetriever = new HashMap<String, String>();
sendDataToOBD(btSocketConnected, "ATZ\r");
dataRetriever.put("Reset", readDataFromOBD(btSocketConnected));
sendDataToOBD(btSocketConnected, "ATS0\r");
dataRetriever.put("Space Control", readDataFromOBD(btSocketConnected));
sendDataToOBD(btSocketConnected, "ATE0\r");
dataRetriever.put("Echo control", readDataFromOBD(btSocketConnected));
sendDataToOBD(btSocketConnected, "ATL0\r");
dataRetriever.put("Line feed", readDataFromOBD(btSocketConnected));
sendDataToOBD(btSocketConnected, "ATAT0\r");
dataRetriever
.put("Adaptive Timing", readDataFromOBD(btSocketConnected));
sendDataToOBD(btSocketConnected, "ATST10\r");
dataRetriever.put("Time Out", readDataFromOBD(btSocketConnected));
sendDataToOBD(btSocketConnected, "ATI\r");
dataRetriever.put("Device Description",
readDataFromOBD(btSocketConnected));
sendDataToOBD(btSocketConnected, "ATDP\r");
dataRetriever.put("Protocol Information1",
readDataFromOBD(btSocketConnected));
sendDataToOBD(btSocketConnected, "ATSPA0\r");
dataRetriever
.put("Auto Protocol",
readBytesFromOBD(btSocketConnected, paramClassName,
methodName));
sendDataToOBD(btSocketConnected, "010C\r");
dataRetriever
.put("RPM param",
readBytesFromOBD(btSocketConnected, paramClassName,
methodName));
sendDataToOBD(btSocketConnected, "010D\r");
dataRetriever
.put("Speed parameters",
readBytesFromOBD(btSocketConnected, paramClassName,
methodName));
sendDataToOBD(btSocketConnected, "0104\r");
dataRetriever
.put("engine load value parameters",
readBytesFromOBD(btSocketConnected, paramClassName,
methodName));
sendDataToOBD(btSocketConnected, "0105\r");
dataRetriever
.put("Engine coolant temperature parameters",
readBytesFromOBD(btSocketConnected, paramClassName,
methodName));
sendDataToOBD(btSocketConnected, "012F\r");
dataRetriever
.put("Fuel Level Input",
readBytesFromOBD(btSocketConnected, paramClassName,
methodName));
return dataRetriever;
}
public class ConnectThread extends Thread {
BluetoothDevice btdevice = null;
BluetoothSocket btSocket = null;
BluetoothAdapter btAdapter = null;
private boolean btconnected;
public ConnectThread(BluetoothDevice btDevObject,
BluetoothSocket btSocketObject, UUID uidValue,
BluetoothAdapter bluetoothAdapterObject) {
btdevice = btDevObject;
btSocket = btSocketObject;
btAdapter = bluetoothAdapterObject;
try {
/*
* Create the Bluetooth Socket
*/
BluetoothSocket temporaryObject = btdevconnected
.createRfcommSocketToServiceRecord(uidValue);
if (temporaryObject != null) {
btSocket = temporaryObject;
}
return;
} catch (IOException e) {
e.printStackTrace();
}
}
public void cancel() {
try {
if (btSocket != null) {
btSocket.close();
}
return;
} catch (IOException localIOException) {
localIOException.printStackTrace();
}
}
public void run() {
btAdapter.cancelDiscovery();
try {
// Connect to socket
btSocket.connect();
btconnected = true;
return;
} catch (IOException localIOException1) {
try {
btSocket.close();
return;
} catch (IOException localIOException2) {
localIOException2.printStackTrace();
}
}
}
public boolean getStatus() {
return btconnected;
}
public BluetoothSocket getSocket() {
return btSocket;
}
}
private String readBytesFromOBD(BluetoothSocket btSocketConnected,
String paramClassName, String methodName) {
new Thread(new BluetoothSocketListener(btSocketConnected,
paramClassName, methodName)).start();
return null;
}
public static class MessageSender {
private static String message;
public MessageSender(String dmessage) {
message = dmessage;
}
public static String getMessage() {
return message;
}
public static void setMessage(String dmessage) {
message = dmessage;
}
public static void getOBDdata(String dmessage) {
setMessage(dmessage);
FileWriter fWriter;
try {
fWriter = new FileWriter(obdRetriver, true);
fWriter.append("\r\n");
fWriter.write("Data passed to UI from OBD");
fWriter.append("\r\n");
fWriter.write(dmessage);
fWriter.flush();
fWriter.close();
} catch (Exception fileObjectException) {
fileObjectException.printStackTrace();
}
if (message.replace(" ", "").indexOf("NODATA") != -1) {
} else {
while (true) {
String str1 = null;
int j;
int i = message.length();
j = 0;
if (i > 4) {
str1 = message.substring(0, 4);
boolean bool = message.substring(0, 2).equals("41");
j = 0;
if (!bool)
;
}
try {
int i4 = Integer.parseInt(
message.substring(4, message.length()), 16);
j = i4;
if (str1.equals("410C")) {
int i3 = j / 4;
rpm = "" + i3;
}
if (str1.equals("410D")) {
speed = "" + j;
Log.d("Speed", "" + j);
}
if (str1.equals("4104")) {
engineAttributes = "" + j * 100 / 255;
Log.d("Calculated engine load value"
+ engineAttributes, "");
}
if (str1.equals("4105")) {
engineCoolantAttributes = "" + (j - 40) + ""
+ "C°";
Log.d("Engine coolant temperature",
engineCoolantAttributes);
}
if (str1.equals("412F")) {
fuelLevel = j * 100 / 255 + "";
Log.d("Fuel Level Input" + fuelLevel, "");
}
((Activity) contextObject)
.runOnUiThread(new Runnable() {
@Override
public void run() {
showRPM.setText("RPM:" + rpm);
showSpeed.setText("Speed" + speed);
showEngineAttributes
.setText("Calculated engine load value"
+ engineAttributes);
showEngineCoolantAttribute
.setText(engineCoolantAttributes);
showFuelLevel
.setText("Fuel Level Input"
+ fuelLevel);
}
});
} catch (NumberFormatException localNumberFormatException) {
while (true)
j = 0;
} catch (NullPointerException nullPointerException) {
nullPointerException.printStackTrace();
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment