├── res
├── drawable-hdpi
│ ├── car.png
│ ├── mpg.png
│ ├── icon.png
│ ├── pump.gif
│ ├── temp.png
│ ├── compass.png
│ ├── ic_launcher.png
│ ├── accel_gauge.xml
│ └── coolant_gauge.xml
├── drawable-ldpi
│ └── ic_launcher.png
├── drawable-mdpi
│ └── ic_launcher.png
├── values
│ └── strings.xml
├── layout
│ ├── command.xml
│ └── main.xml
└── xml
│ └── preferences.xml
├── bin
└── classes
│ └── awis
│ └── obd
│ ├── activity
│ ├── R.class
│ ├── R$id.class
│ ├── R$attr.class
│ ├── R$xml.class
│ ├── R$layout.class
│ ├── R$string.class
│ ├── R$drawable.class
│ ├── ObdReaderMainActivity.class
│ ├── ObdReaderCommandActivity.class
│ ├── ObdReaderConfigActivity.class
│ ├── ObdReaderMainActivity$1.class
│ ├── ObdReaderMainActivity$2.class
│ ├── ObdReaderMainActivity$3.class
│ ├── ObdReaderCommandActivity$1.class
│ ├── ObdReaderCommandActivity$2.class
│ ├── ObdReaderConfigActivity$1.class
│ ├── ObdReaderMainActivity$UpdateThread.class
│ └── ObdReaderCommandActivity$ObdReaderCommandActivityWorkerThread.class
│ ├── command
│ ├── ObdCommand.class
│ ├── IntObdCommand.class
│ ├── ObdMultiCommand.class
│ ├── SpeedObdCommand.class
│ ├── TempObdCommand.class
│ ├── DtcNumberObdCommand.class
│ ├── EngineRPMObdCommand.class
│ ├── FuelTrimObdCommand.class
│ ├── PressureObdCommand.class
│ ├── ThrottleObdCommand.class
│ ├── FuelEconomyObdCommand.class
│ ├── FuelPressureObdCommand.class
│ ├── MassAirFlowObdCommand.class
│ ├── TroubleCodesObdCommand.class
│ ├── AirIntakeTempObdCommand.class
│ ├── EngineRunTimeObdCommand.class
│ ├── FuelEconomyMAPObdCommand.class
│ ├── TimingAdvanceObdCommand.class
│ ├── CommandEquivRatioObdCommand.class
│ ├── AverageFuelEconomyObdCommand.class
│ ├── IntakeManifoldPressureObdCommand.class
│ └── FuelEconomyCommandedMAPObdCommand.class
│ ├── config
│ └── ObdConfig.class
│ ├── io
│ ├── ObdConnectThread.class
│ ├── ObdReaderService.class
│ ├── ObdCommandConnectThread.class
│ ├── ObdReaderServiceConnection.class
│ ├── ObdReaderService$ObdReaderServiceBinder.class
│ └── ObdReaderService$ObdReaderServiceWorkerThread.class
│ ├── drawable
│ ├── AccelGaugeView.class
│ ├── CoolantGaugeView.class
│ └── GradientGaugeView.class
│ └── exception
│ └── ConfigException.class
├── README
├── src
└── awis
│ └── obd
│ ├── command
│ ├── AirIntakeTempObdCommand.java
│ ├── FuelPressureObdCommand.java
│ ├── IntakeManifoldPressureObdCommand.java
│ ├── SpeedObdCommand.java
│ ├── TempObdCommand.java
│ ├── ThrottleObdCommand.java
│ ├── FuelTrimObdCommand.java
│ ├── PressureObdCommand.java
│ ├── TimingAdvanceObdCommand.java
│ ├── MassAirFlowObdCommand.java
│ ├── EngineRPMObdCommand.java
│ ├── EngineRunTimeObdCommand.java
│ ├── DtcNumberObdCommand.java
│ ├── IntObdCommand.java
│ ├── CommandEquivRatioObdCommand.java
│ ├── ObdMultiCommand.java
│ ├── AverageFuelEconomyObdCommand.java
│ ├── FuelEconomyObdCommand.java
│ ├── TroubleCodesObdCommand.java
│ ├── FuelEconomyCommandedMAPObdCommand.java
│ ├── FuelEconomyMAPObdCommand.java
│ └── ObdCommand.java
│ ├── exception
│ └── ConfigException.java
│ ├── io
│ ├── ObdReaderServiceConnection.java
│ ├── ObdCommandConnectThread.java
│ ├── ObdReaderService.java
│ └── ObdConnectThread.java
│ ├── drawable
│ ├── GradientGaugeView.java
│ ├── AccelGaugeView.java
│ └── CoolantGaugeView.java
│ ├── config
│ └── ObdConfig.java
│ └── activity
│ ├── ObdReaderCommandActivity.java
│ ├── ObdReaderConfigActivity.java
│ └── ObdReaderMainActivity.java
├── project.properties
├── .classpath
├── .project
├── proguard.cfg
└── AndroidManifest.xml
/res/drawable-hdpi/car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/res/drawable-hdpi/car.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/mpg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/res/drawable-hdpi/mpg.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/res/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/pump.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/res/drawable-hdpi/pump.gif
--------------------------------------------------------------------------------
/res/drawable-hdpi/temp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/res/drawable-hdpi/temp.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/compass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/res/drawable-hdpi/compass.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/R.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/R.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/R$id.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/R$id.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/R$attr.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/R$attr.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/R$xml.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/R$xml.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/R$layout.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/R$layout.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/R$string.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/R$string.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/ObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/ObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/config/ObdConfig.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/config/ObdConfig.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/R$drawable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/R$drawable.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/io/ObdConnectThread.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/io/ObdConnectThread.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/io/ObdReaderService.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/io/ObdReaderService.class
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | This app is cloned from http://code.google.com/p/android-obd-reader/
2 | The purpose of this app is to communicate to ELM327 reader using wizard for easier usage.
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/IntObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/IntObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/ObdMultiCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/ObdMultiCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/SpeedObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/SpeedObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/TempObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/TempObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/drawable/AccelGaugeView.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/drawable/AccelGaugeView.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/drawable/CoolantGaugeView.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/drawable/CoolantGaugeView.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/exception/ConfigException.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/exception/ConfigException.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/DtcNumberObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/DtcNumberObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/EngineRPMObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/EngineRPMObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/FuelTrimObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/FuelTrimObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/PressureObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/PressureObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/ThrottleObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/ThrottleObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/drawable/GradientGaugeView.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/drawable/GradientGaugeView.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/io/ObdCommandConnectThread.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/io/ObdCommandConnectThread.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/ObdReaderMainActivity.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/ObdReaderMainActivity.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/FuelEconomyObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/FuelEconomyObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/FuelPressureObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/FuelPressureObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/MassAirFlowObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/MassAirFlowObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/TroubleCodesObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/TroubleCodesObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/io/ObdReaderServiceConnection.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/io/ObdReaderServiceConnection.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/ObdReaderCommandActivity.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/ObdReaderCommandActivity.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/ObdReaderConfigActivity.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/ObdReaderConfigActivity.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/ObdReaderMainActivity$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/ObdReaderMainActivity$1.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/ObdReaderMainActivity$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/ObdReaderMainActivity$2.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/ObdReaderMainActivity$3.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/ObdReaderMainActivity$3.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/AirIntakeTempObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/AirIntakeTempObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/EngineRunTimeObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/EngineRunTimeObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/FuelEconomyMAPObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/FuelEconomyMAPObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/TimingAdvanceObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/TimingAdvanceObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/ObdReaderCommandActivity$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/ObdReaderCommandActivity$1.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/ObdReaderCommandActivity$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/ObdReaderCommandActivity$2.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/ObdReaderConfigActivity$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/ObdReaderConfigActivity$1.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/CommandEquivRatioObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/CommandEquivRatioObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/AverageFuelEconomyObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/AverageFuelEconomyObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/IntakeManifoldPressureObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/IntakeManifoldPressureObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/ObdReaderMainActivity$UpdateThread.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/ObdReaderMainActivity$UpdateThread.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/command/FuelEconomyCommandedMAPObdCommand.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/command/FuelEconomyCommandedMAPObdCommand.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/io/ObdReaderService$ObdReaderServiceBinder.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/io/ObdReaderService$ObdReaderServiceBinder.class
--------------------------------------------------------------------------------
/bin/classes/awis/obd/io/ObdReaderService$ObdReaderServiceWorkerThread.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/io/ObdReaderService$ObdReaderServiceWorkerThread.class
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | OBD Test App
4 | Choose a command
5 |
6 |
--------------------------------------------------------------------------------
/bin/classes/awis/obd/activity/ObdReaderCommandActivity$ObdReaderCommandActivityWorkerThread.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/awisalkarni/OBD-Bluetooth-Reader/HEAD/bin/classes/awis/obd/activity/ObdReaderCommandActivity$ObdReaderCommandActivityWorkerThread.class
--------------------------------------------------------------------------------
/res/drawable-hdpi/accel_gauge.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/coolant_gauge.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/src/awis/obd/command/AirIntakeTempObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | public class AirIntakeTempObdCommand extends TempObdCommand{
4 |
5 | public AirIntakeTempObdCommand() {
6 | super("010F","Air Intake Temp","C","F");
7 | }
8 | public AirIntakeTempObdCommand(AirIntakeTempObdCommand other) {
9 | super(other);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/awis/obd/exception/ConfigException.java:
--------------------------------------------------------------------------------
1 | package awis.obd.exception;
2 |
3 | public class ConfigException extends Exception {
4 |
5 | public ConfigException(String msg) {
6 | // TODO Auto-generated constructor stub
7 | }
8 |
9 | /**
10 | *
11 | */
12 | private static final long serialVersionUID = -7089923352166624943L;
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/src/awis/obd/command/FuelPressureObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | public class FuelPressureObdCommand extends PressureObdCommand{
4 |
5 | public FuelPressureObdCommand() {
6 | super("010A","Fuel Press","kPa","atm");
7 | }
8 | public FuelPressureObdCommand(FuelPressureObdCommand other) {
9 | super(other);
10 | }
11 | public int transform(int b) {
12 | return b*3;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/awis/obd/command/IntakeManifoldPressureObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | public class IntakeManifoldPressureObdCommand extends PressureObdCommand {
4 |
5 | public IntakeManifoldPressureObdCommand() {
6 | super("010B","Intake Manifold Press","kPa","atm");
7 | }
8 | public IntakeManifoldPressureObdCommand(IntakeManifoldPressureObdCommand other) {
9 | super(other);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system use,
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 |
10 | # Project target.
11 | target=android-15
12 |
--------------------------------------------------------------------------------
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/awis/obd/command/SpeedObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | import awis.obd.config.ObdConfig;
4 |
5 | public class SpeedObdCommand extends IntObdCommand {
6 |
7 | public SpeedObdCommand() {
8 | super("010D",ObdConfig.SPEED,"km/h","mph");
9 | }
10 | public SpeedObdCommand(SpeedObdCommand other) {
11 | super(other);
12 | }
13 | @Override
14 | public int getImperialInt() {
15 | if (intValue <= 0) {
16 | return 0;
17 | }
18 | return (int)(intValue * .625);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/awis/obd/command/TempObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | public class TempObdCommand extends IntObdCommand{
4 |
5 | public TempObdCommand(String cmd, String desc, String resType, String impType) {
6 | super(cmd, desc, resType, impType);
7 | }
8 | public TempObdCommand(TempObdCommand other) {
9 | super(other);
10 | }
11 | protected int transform(int b) {
12 | return b-40;
13 | }
14 | @Override
15 | public int getImperialInt() {
16 | return (intValue*9/5) + 32;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/awis/obd/command/ThrottleObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | public class ThrottleObdCommand extends IntObdCommand {
4 |
5 | public ThrottleObdCommand(String cmd, String desc, String resType) {
6 | super(cmd,desc,resType,resType);
7 | }
8 | public ThrottleObdCommand() {
9 | super("0111","Throttle Position","%","%");
10 | }
11 | public ThrottleObdCommand(ThrottleObdCommand other) {
12 | super(other);
13 | }
14 | protected int transform(int b) {
15 | return (int)((double)(b*100)/255.0);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/awis/obd/command/FuelTrimObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | public class FuelTrimObdCommand extends IntObdCommand {
4 |
5 | public FuelTrimObdCommand(String cmd, String desc, String resType) {
6 | super(cmd,desc,resType,resType);
7 | }
8 | public FuelTrimObdCommand(FuelTrimObdCommand other) {
9 | super(other);
10 | }
11 |
12 | public FuelTrimObdCommand() {
13 | super("0107","Long Term Fuel Trim","%","%");
14 | }
15 |
16 | @Override
17 | public int transform(int b) {
18 | double perc = (b-128)*(100.0/128);
19 | return (int)perc;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/awis/obd/command/PressureObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | public class PressureObdCommand extends IntObdCommand {
4 |
5 | public PressureObdCommand(String cmd, String desc, String resType, String impType) {
6 | super(cmd,desc,resType,impType);
7 | }
8 | public PressureObdCommand(PressureObdCommand other) {
9 | super(other);
10 | }
11 | public String formatResult() {
12 | String res = super.formatResult();
13 | if (!isImperial() || "NODATA".equals(res)) {
14 | return res;
15 | }
16 | double atm = intValue * 1.0 / 101.3;
17 | return String.format("%.2f %s", atm, impType);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/awis/obd/command/TimingAdvanceObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | public class TimingAdvanceObdCommand extends ObdCommand {
4 |
5 | public TimingAdvanceObdCommand() {
6 | super("010E","Timing Advance","deg","deg");
7 | }
8 | public TimingAdvanceObdCommand(TimingAdvanceObdCommand other) {
9 | super(other);
10 | }
11 | public String formatResult() {
12 | String res = super.formatResult();
13 | if ("NODATA".equals(res)) {
14 | return "NODATA";
15 | }
16 | String A = res.substring(4,6);
17 | double a = (double)Integer.parseInt(A,16);
18 | double adv = (a/2.0) / 64;
19 | return String.format("%.1f %s", adv, resType);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/awis/obd/io/ObdReaderServiceConnection.java:
--------------------------------------------------------------------------------
1 | package awis.obd.io;
2 |
3 | import android.content.ComponentName;
4 | import android.content.ServiceConnection;
5 | import android.os.IBinder;
6 |
7 | public class ObdReaderServiceConnection implements ServiceConnection {
8 |
9 | private ObdReaderService service = null;
10 | public void onServiceConnected(ComponentName name, IBinder service) {
11 | this.service = ((ObdReaderService.ObdReaderServiceBinder)service).getService();
12 | }
13 | public void onServiceDisconnected(ComponentName name) {
14 | service = null;
15 | }
16 | public ObdReaderService getService() {
17 | return service;
18 | }
19 | public boolean isRunning() {
20 | if (service == null) {
21 | return false;
22 | }
23 | return service.isRunning();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/awis/obd/command/MassAirFlowObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | public class MassAirFlowObdCommand extends ObdCommand {
4 |
5 | /**
6 | * @uml.property name="maf"
7 | */
8 | private double maf = -9999.0;
9 | public MassAirFlowObdCommand() {
10 | super("0110","Mass Air Flow","g/s","g/s");
11 | }
12 | public MassAirFlowObdCommand(MassAirFlowObdCommand other) {
13 | super(other);
14 | }
15 | public String formatResult() {
16 | String res = super.formatResult();
17 | if ("NODATA".equals(res)) {
18 | return "NODATA";
19 | }
20 | String A = res.substring(4,6);
21 | String B = res.substring(6,8);
22 | int a = Integer.parseInt(A,16);
23 | int b = Integer.parseInt(B,16);
24 | maf = ((256.0*a)+b) / 100.0;
25 | return Double.toString(maf);
26 | }
27 | double getMAF() {
28 | return maf;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/awis/obd/command/EngineRPMObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | import awis.obd.config.ObdConfig;
4 |
5 | public class EngineRPMObdCommand extends IntObdCommand{
6 |
7 | public EngineRPMObdCommand() {
8 | super("010C",ObdConfig.RPM,"RPM","RPM");
9 | }
10 | public EngineRPMObdCommand(EngineRPMObdCommand other) {
11 | super(other);
12 | }
13 | public String formatResult() {
14 | String res = getResult();
15 | String[] ress = res.split("\r");
16 | res = ress[0].replace(" ","");
17 | if ("NODATA".equals(res)) {
18 | return "NODATA";
19 | }
20 | String byteStrOne = res.substring(4,6);
21 | String byteStrTwo = res.substring(6,8);
22 | int a = Integer.parseInt(byteStrOne,16);
23 | int b = Integer.parseInt(byteStrTwo,16);
24 | intValue = transform(a,b);
25 | return String.format("%d %s", intValue, resType);
26 | }
27 | protected int transform(int a, int b) {
28 | return (int)((double)(a*256+b)/4.0);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/awis/obd/command/EngineRunTimeObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | import awis.obd.config.ObdConfig;
4 |
5 |
6 |
7 | public class EngineRunTimeObdCommand extends ObdCommand {
8 |
9 | public EngineRunTimeObdCommand() {
10 | super("011F",ObdConfig.RUN_TIME,"","");
11 | }
12 | public EngineRunTimeObdCommand(EngineRunTimeObdCommand other) {
13 | super(other);
14 | }
15 | @Override
16 | public String formatResult() {
17 | String res = super.formatResult();
18 | if ("NODATA".equals(res)) {
19 | return "NODATA";
20 | }
21 | String A = res.substring(4,6);
22 | String B = res.substring(6,8);
23 | int a = Integer.parseInt(A,16);
24 | int b = Integer.parseInt(B,16);
25 | int sec = (a*256)+b;
26 | String hh = String.format("%02d", sec/3600);
27 | String mm = String.format("%02d", (sec%3600)/60);
28 | String ss = String.format("%02d", sec%60);
29 | String time = String.format("%s:%s:%s", hh,mm,ss);
30 | return time;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/awis/obd/command/DtcNumberObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | public class DtcNumberObdCommand extends ObdCommand {
4 |
5 | /**
6 | * @uml.property name="codeCount"
7 | */
8 | private int codeCount = -1;
9 | /**
10 | * @uml.property name="milOn"
11 | */
12 | private boolean milOn = false;
13 | public DtcNumberObdCommand() {
14 | super("0101","DTC Status","","");
15 | }
16 | public DtcNumberObdCommand(DtcNumberObdCommand other) {
17 | super(other);
18 | }
19 | public String formatResult() {
20 | String res = super.formatResult();
21 | String byte1 = res.substring(4,6);
22 | int mil = Integer.parseInt(byte1,16);
23 | String result = "MIL is off, ";
24 | if ((mil & 0x80) == 1) {
25 | milOn = true;
26 | result = "MIL is on, ";
27 | }
28 | codeCount = mil & 0x7f;
29 | result += codeCount + " codes";
30 | return result;
31 | }
32 | /**
33 | * @return
34 | * @uml.property name="codeCount"
35 | */
36 | public int getCodeCount() {
37 | return codeCount;
38 | }
39 | public boolean getMilOn() {
40 | return milOn;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/awis/obd/command/IntObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | public class IntObdCommand extends ObdCommand {
4 |
5 | /**
6 | * @uml.property name="intValue"
7 | */
8 | protected int intValue = -9999;
9 | public IntObdCommand(String cmd, String desc, String resType, String impType) {
10 | super(cmd, desc, resType, impType);
11 | }
12 | public IntObdCommand(IntObdCommand other) {
13 | super(other);
14 | }
15 | public String formatResult() {
16 | String res = super.formatResult();
17 | if ("NODATA".equals(res)) {
18 | return "NODATA";
19 | }
20 | String byteStr = res.substring(4,6);
21 | int b = Integer.parseInt(byteStr,16);
22 | intValue = transform(b);
23 | if (isImperial()) {
24 | return String.format("%s %s", Integer.toString(getImperialInt()), impType);
25 | } else {
26 | return String.format("%s %s", Integer.toString(intValue), resType);
27 | }
28 | }
29 | protected int transform(int b) {
30 | return b;
31 | }
32 | public int getInt() {
33 | return intValue;
34 | }
35 | public int getImperialInt() {
36 | return intValue;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/res/layout/command.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
19 |
22 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/awis/obd/command/CommandEquivRatioObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | public class CommandEquivRatioObdCommand extends ObdCommand {
4 |
5 | /**
6 | * @uml.property name="ratio"
7 | */
8 | private double ratio = 1.0;
9 | public CommandEquivRatioObdCommand() {
10 | super("0144","Command Equivalence Ratio","","");
11 | }
12 | public CommandEquivRatioObdCommand(String cmd, String desc, String resType, String impType) {
13 | super(cmd, desc, resType, impType);
14 | }
15 | public CommandEquivRatioObdCommand(CommandEquivRatioObdCommand other) {
16 | super(other);
17 | }
18 | public String formatResult() {
19 | String res = super.formatResult();
20 | if ("NODATA".equals(res)) {
21 | return "NODATA";
22 | }
23 | try {
24 | String A = res.substring(4,6);
25 | String B = res.substring(6,8);
26 | int a = Integer.parseInt(A,16);
27 | int b = Integer.parseInt(B,16);
28 | ratio = ((a*256)+b)*0.0000305;
29 | } catch (Exception e) {
30 | setError(e);
31 | }
32 | return String.format("%.2f", ratio);
33 | }
34 | /**
35 | * @return
36 | * @uml.property name="ratio"
37 | */
38 | double getRatio() {
39 | return ratio;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | OBD Reader
4 | @key 32303037303533312D3130204F4244205265616465722F41776973
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 | com.soyatec.additional.Builder
30 |
31 |
32 |
33 |
34 |
35 | com.android.ide.eclipse.adt.AndroidNature
36 | org.eclipse.jdt.core.javanature
37 | com.soyatec.additional.Nature
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/awis/obd/command/ObdMultiCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | import java.io.IOException;
4 |
5 | public class ObdMultiCommand extends ObdCommand {
6 |
7 | /**
8 | * @uml.property name="cmds" multiplicity="(0 -1)" dimension="1"
9 | */
10 | private String[] cmds;
11 |
12 | public ObdMultiCommand(String[] cmds, String desc, String resType, String impType) {
13 | super(null, desc, resType, impType);
14 | this.cmds = cmds;
15 | }
16 | public ObdMultiCommand(ObdMultiCommand other) {
17 | this(other.cmds, other.desc, other.resType, other.impType);
18 | }
19 | public void run() {
20 | buff.clear();
21 | for (int i = 0; i < cmds.length; i++) {
22 | String cmd = cmds[i];
23 | sendCmd(cmd);
24 | readResult();
25 | }
26 | }
27 | protected void readResult() {
28 | byte c = 0;
29 | try {
30 | while ((char)(c = (byte)in.read()) != '>') {
31 | buff.add(c);
32 | }
33 | buff.add((byte)'\n');
34 | } catch (IOException e) {
35 | }
36 | }
37 | public String getCmd() {
38 | String cmd = "";
39 | for (int i = 0; i < cmds.length; i++) {
40 | cmd += cmds[i];
41 | if (i+1 < cmds.length) {
42 | cmd += ",";
43 | }
44 | }
45 | return cmd;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/awis/obd/command/AverageFuelEconomyObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | public class AverageFuelEconomyObdCommand extends ObdCommand {
4 |
5 | public static final String FUEL_ECONOMY_KEY = "Fuel Economy";
6 | public static final String AVG_FUEL_ECONOMY_KEY = "Fuel Economy Average";
7 | public static final String AVG_FUEL_ECONOMY_COUNT_KEY = "Average Fuel Economy Count";
8 |
9 | public AverageFuelEconomyObdCommand() {
10 | super("",AVG_FUEL_ECONOMY_KEY,"kmpg","mpg");
11 | }
12 | public AverageFuelEconomyObdCommand(AverageFuelEconomyObdCommand other) {
13 | super(other);
14 | }
15 | public String formatResult() {
16 | Double ampg = 0.0;
17 | Integer count = 0;
18 | Double mpg = 0.0;
19 | if (data.containsKey(AVG_FUEL_ECONOMY_KEY)) {
20 | ampg = (Double)data.get(AVG_FUEL_ECONOMY_KEY);
21 | count = (Integer)data.get(AVG_FUEL_ECONOMY_COUNT_KEY);
22 | }
23 | if (data.containsKey(FUEL_ECONOMY_KEY)) {
24 | mpg = (Double)data.get(FUEL_ECONOMY_KEY);
25 | }
26 | if (mpg > 0) {
27 | ampg += mpg;
28 | count += 1;
29 | data.put(AVG_FUEL_ECONOMY_KEY, ampg);
30 | data.put(AVG_FUEL_ECONOMY_COUNT_KEY, count);
31 | }
32 | if (count > 0) {
33 | ampg = ampg / (double)count;
34 | }
35 | return String.format("%.1f mpg", ampg);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/proguard.cfg:
--------------------------------------------------------------------------------
1 | -optimizationpasses 5
2 | -dontusemixedcaseclassnames
3 | -dontskipnonpubliclibraryclasses
4 | -dontpreverify
5 | -verbose
6 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
7 |
8 | -keep public class * extends android.app.Activity
9 | -keep public class * extends android.app.Application
10 | -keep public class * extends android.app.Service
11 | -keep public class * extends android.content.BroadcastReceiver
12 | -keep public class * extends android.content.ContentProvider
13 | -keep public class * extends android.app.backup.BackupAgentHelper
14 | -keep public class * extends android.preference.Preference
15 | -keep public class com.android.vending.licensing.ILicensingService
16 |
17 | -keepclasseswithmembernames class * {
18 | native ;
19 | }
20 |
21 | -keepclasseswithmembers class * {
22 | public (android.content.Context, android.util.AttributeSet);
23 | }
24 |
25 | -keepclasseswithmembers class * {
26 | public (android.content.Context, android.util.AttributeSet, int);
27 | }
28 |
29 | -keepclassmembers class * extends android.app.Activity {
30 | public void *(android.view.View);
31 | }
32 |
33 | -keepclassmembers enum * {
34 | public static **[] values();
35 | public static ** valueOf(java.lang.String);
36 | }
37 |
38 | -keep class * implements android.os.Parcelable {
39 | public static final android.os.Parcelable$Creator *;
40 | }
41 |
--------------------------------------------------------------------------------
/src/awis/obd/drawable/GradientGaugeView.java:
--------------------------------------------------------------------------------
1 | package awis.obd.drawable;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.graphics.drawable.Drawable;
7 | import android.graphics.drawable.ShapeDrawable;
8 | import android.graphics.drawable.shapes.RectShape;
9 | import android.util.AttributeSet;
10 | import android.util.Log;
11 | import android.view.View;
12 |
13 | public abstract class GradientGaugeView extends View {
14 |
15 | /**
16 | * @uml.property name="context"
17 | * @uml.associationEnd multiplicity="(1 1)"
18 | */
19 | protected Context context = null;
20 | /**
21 | * @uml.property name="paint"
22 | * @uml.associationEnd multiplicity="(1 1)"
23 | */
24 | protected Paint paint = null;
25 |
26 | public GradientGaugeView(Context context, AttributeSet attrs) {
27 | super(context, attrs);
28 | this.context = context;
29 | paint = new Paint();
30 | }
31 |
32 | @Override
33 | protected abstract void onDraw(Canvas canvas);
34 |
35 | protected void drawGradient(Canvas canvas, Drawable container, int offset, double value, double range) {
36 | int width = getWidth();
37 | int height = getHeight();
38 | int left = getLeft();
39 | int top = getTop();
40 | Log.i("width",String.format("%d %d",width,left));
41 | container.setBounds(left,top+offset,left+width,top+height+offset);
42 | container.draw(canvas);
43 | ShapeDrawable cover = new ShapeDrawable(new RectShape());
44 | double perc = value / range;
45 | int coverLeft = (int)(width * perc);
46 | cover.setBounds(left+coverLeft, top+offset, left+width, top+height+offset);
47 | cover.draw(canvas);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/awis/obd/drawable/AccelGaugeView.java:
--------------------------------------------------------------------------------
1 | package awis.obd.drawable;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.graphics.Typeface;
9 | import android.graphics.drawable.Drawable;
10 | import android.util.AttributeSet;
11 | import awis.obd.activity.R;
12 |
13 | public class AccelGaugeView extends GradientGaugeView {
14 |
15 | public final static int TEXT_SIZE = 15;
16 | public final static int range = 20;
17 | /**
18 | * @uml.property name="accel"
19 | */
20 | private double accel = 2;
21 |
22 | public AccelGaugeView(Context context, AttributeSet attrs) {
23 | super(context, attrs);
24 | this.context = context;
25 | paint = new Paint();
26 | paint.setTextSize(TEXT_SIZE);
27 | Typeface bold = Typeface.defaultFromStyle(Typeface.BOLD);
28 | paint.setTypeface(bold);
29 | paint.setStrokeWidth(3);
30 | paint.setStyle(Paint.Style.FILL);
31 | }
32 |
33 | /**
34 | * @param accel
35 | * @uml.property name="accel"
36 | */
37 | public void setAccel(double accel) {
38 | this.accel = accel;
39 | }
40 |
41 | @Override
42 | protected void onDraw(Canvas canvas) {
43 | Resources res = context.getResources();
44 | Drawable container = (Drawable) res.getDrawable(R.drawable.accel_gauge);
45 | int width = getWidth();
46 | int left = getLeft();
47 | int top = getTop();
48 | paint.setColor(Color.GREEN);
49 | canvas.drawText("Soft",left,top+TEXT_SIZE,paint);
50 | paint.setColor(Color.RED);
51 | canvas.drawText("Hard", left+width-TEXT_SIZE*3, top+TEXT_SIZE, paint);
52 | drawGradient(canvas, container, TEXT_SIZE+5, accel, range);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/awis/obd/io/ObdCommandConnectThread.java:
--------------------------------------------------------------------------------
1 | package awis.obd.io;
2 |
3 | import awis.obd.activity.ObdReaderCommandActivity;
4 | import awis.obd.command.ObdCommand;
5 | import awis.obd.config.ObdConfig;
6 |
7 | import android.bluetooth.BluetoothDevice;
8 |
9 | public class ObdCommandConnectThread extends ObdConnectThread {
10 |
11 | /**
12 | * @uml.property name="cmd"
13 | * @uml.associationEnd multiplicity="(1 1)"
14 | */
15 | private ObdCommand cmd = null;
16 | /**
17 | * @uml.property name="activity"
18 | * @uml.associationEnd multiplicity="(1 1)"
19 | */
20 | private ObdReaderCommandActivity activity = null;
21 |
22 | public ObdCommandConnectThread(BluetoothDevice dev, ObdReaderCommandActivity activity, ObdCommand cmd, double ed, double ve, boolean imperialUnits) {
23 | super(dev, null, null, null, 0, ed, ve, imperialUnits, false, ObdConfig.getAllCommands());
24 | this.cmd = cmd;
25 | this.activity = activity;
26 | }
27 |
28 | public void run() {
29 | try {
30 | activity.logMsg("Starting device...");
31 | startDevice();
32 | activity.logMsg("Device started, running " + cmd.getCmd() + "...");
33 | cmd.setConnectThread(this);
34 | String res = runCommand(cmd);
35 | String rawRes = cmd.getResult().replace("\r","\\r").replace("\n","\\n");
36 | activity.logMsg("Raw result is '" + rawRes + "'");
37 | results.put(cmd.getDesc(), res);
38 | if (cmd.getError() != null) {
39 | activity.logMsg(cmd.getError().getMessage());
40 | activity.logMsg(getStackTrace(cmd.getError()));
41 | }
42 | } catch (Exception e) {
43 | activity.logMsg("Error running command: " + e.getMessage() + ", result was: '" + cmd.getResult() + "'");
44 | activity.logMsg("Error was: " + getStackTrace(e));
45 | } finally {
46 | close();
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/awis/obd/command/FuelEconomyObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | import awis.obd.config.ObdConfig;
4 |
5 | public class FuelEconomyObdCommand extends ObdCommand {
6 |
7 | public static final double AIR_FUEL_RATIO = 14.64;
8 | public static final double FUEL_DENSITY_GRAMS_PER_LITER = 720.0;
9 | /**
10 | * @uml.property name="fuelEcon"
11 | */
12 | protected double fuelEcon = -9999.0;
13 |
14 | public FuelEconomyObdCommand(String cmd, String desc, String resType, String impType) {
15 | super(cmd,desc,resType,impType);
16 | }
17 | public FuelEconomyObdCommand() {
18 | super("",ObdConfig.FUEL_ECON,"kml","mpg");
19 | }
20 | public FuelEconomyObdCommand(FuelEconomyObdCommand other) {
21 | super(other);
22 | }
23 | public void run() {
24 | try {
25 | MassAirFlowObdCommand maf = new MassAirFlowObdCommand();
26 | SpeedObdCommand speed = new SpeedObdCommand();
27 | runCmd(maf);
28 | maf.formatResult();
29 | double mafV = maf.getMAF();
30 | if (mafV == -9999.0) {
31 | fuelEcon = -9999.0;
32 | }
33 | runCmd(speed);
34 | speed.formatResult();
35 | double speedV = (double)speed.getInt();
36 | fuelEcon = (14.7 * 6.17 * 454.0 * speedV * 0.621371) / (3600.0 * mafV);
37 | } catch (Exception e) {
38 | setError(e);
39 | }
40 | }
41 | public void runCmd(ObdCommand cmd) {
42 | cmd.setInputStream(in);
43 | cmd.setOutputStream(out);
44 | cmd.start();
45 | try {
46 | cmd.join();
47 | } catch (InterruptedException e) {
48 | setError(e);
49 | }
50 | }
51 | public String formatResult() {
52 | if (fuelEcon < 0) {
53 | return "NODATA";
54 | }
55 | if (!isImperial()) {
56 | double kml = fuelEcon * 0.354013;
57 | return String.format("%.1f %s", kml, resType);
58 | }
59 | return String.format("%.1f %s", fuelEcon, impType);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/awis/obd/drawable/CoolantGaugeView.java:
--------------------------------------------------------------------------------
1 | package awis.obd.drawable;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.graphics.Typeface;
9 | import android.graphics.drawable.Drawable;
10 | import android.util.AttributeSet;
11 | import awis.obd.activity.R;
12 |
13 | public class CoolantGaugeView extends GradientGaugeView {
14 |
15 | public final static int min_temp = 35;
16 | public final static int max_temp = 138;
17 | public final static int TEXT_SIZE = 18;
18 | public final static int range = max_temp - min_temp;
19 | /**
20 | * @uml.property name="temp"
21 | */
22 | private int temp = min_temp;
23 |
24 | public CoolantGaugeView(Context context, AttributeSet attrs) {
25 | super(context, attrs);
26 | this.context = context;
27 | paint = new Paint();
28 | paint.setTextSize(TEXT_SIZE);
29 | Typeface bold = Typeface.defaultFromStyle(Typeface.BOLD);
30 | paint.setTypeface(bold);
31 | paint.setStrokeWidth(3);
32 | paint.setStyle(Paint.Style.FILL_AND_STROKE);
33 | }
34 |
35 | /**
36 | * @param temp
37 | * @uml.property name="temp"
38 | */
39 | public void setTemp(int temp) {
40 | this.temp = temp;
41 | if (this.temp < min_temp) {
42 | this.temp = min_temp + 2;
43 | }
44 | if (this.temp > max_temp) {
45 | this.temp = max_temp;
46 | }
47 | invalidate();
48 | }
49 |
50 | @Override
51 | protected void onDraw(Canvas canvas) {
52 | Resources res = context.getResources();
53 | Drawable container = (Drawable) res.getDrawable(R.drawable.coolant_gauge);
54 | int width = getWidth();
55 | int left = getLeft();
56 | int top = getTop();
57 | paint.setColor(Color.BLUE);
58 | canvas.drawText("C",left,top+TEXT_SIZE,paint);
59 | paint.setColor(Color.RED);
60 | canvas.drawText("H", left+width-TEXT_SIZE, top+TEXT_SIZE, paint);
61 | drawGradient(canvas, container, TEXT_SIZE+5, temp-min_temp,range);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/awis/obd/command/TroubleCodesObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | public class TroubleCodesObdCommand extends ObdCommand {
4 |
5 | protected final static char[] dtcLetters = {'P','C','B','U'};
6 | /**
7 | * @uml.property name="codes"
8 | */
9 | private StringBuffer codes = null;
10 | public TroubleCodesObdCommand() {
11 | super("03","Trouble Codes","","");
12 | codes = new StringBuffer();
13 | }
14 | public TroubleCodesObdCommand(String cmd, String desc, String resType, String impType) {
15 | super(cmd, desc, resType, impType);
16 | codes = new StringBuffer();
17 | }
18 | public TroubleCodesObdCommand(TroubleCodesObdCommand other) {
19 | super(other);
20 | codes = new StringBuffer();
21 | }
22 | public void run() {
23 | DtcNumberObdCommand numCmd = new DtcNumberObdCommand();
24 | numCmd.setInputStream(in);
25 | numCmd.setOutputStream(out);
26 | numCmd.start();
27 | try {
28 | numCmd.join();
29 | } catch (InterruptedException e) {
30 | setError(e);
31 | }
32 | int count = numCmd.getCodeCount();
33 | int dtcNum = (count+2)/3;
34 | for (int i = 0; i < dtcNum; i++) {
35 | sendCmd(cmd);
36 | String res = getResult();
37 | for (int j = 0; j < 3; j++) {
38 | String byte1 = res.substring(3+j*6,5+j*6);
39 | String byte2 = res.substring(6+j*6,8+j*6);
40 | int b1 = Integer.parseInt(byte1,16);
41 | int b2 = Integer.parseInt(byte2,16);
42 | int val = (b1 << 8) + b2;
43 | if (val == 0) {
44 | break;
45 | }
46 | String code = "P";
47 | if ((val&0xC000) > 14) {
48 | code = "C";
49 | }
50 | code += Integer.toString((val&0x3000)>>12);
51 | code += Integer.toString((val&0x0fff));
52 | codes.append(code);
53 | codes.append("\n");
54 | }
55 | }
56 | }
57 | public String formatResult() {
58 | String res = getResult();
59 | String[] ress = res.split("\r");
60 | for (String r:ress) {
61 | String k = r.replace("\r","");
62 | codes.append(k);
63 | codes.append("\n");
64 | }
65 | return codes.toString();
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/awis/obd/command/FuelEconomyCommandedMAPObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 |
4 | public class FuelEconomyCommandedMAPObdCommand extends FuelEconomyObdCommand {
5 |
6 | public static final double AIR_FUEL_RATIO = 14.64;
7 | public static final double FUEL_DENSITY_GRAMS_PER_LITER = 720.0;
8 |
9 | public FuelEconomyCommandedMAPObdCommand() {
10 | super("","Fuel Economy Cmd. MAP","kml","mpg");
11 | }
12 | public FuelEconomyCommandedMAPObdCommand(FuelEconomyCommandedMAPObdCommand other) {
13 | super(other);
14 | }
15 | public void run() {
16 | try {
17 | EngineRPMObdCommand rpm = new EngineRPMObdCommand();
18 | AirIntakeTempObdCommand temp = new AirIntakeTempObdCommand();
19 | SpeedObdCommand speed = new SpeedObdCommand();
20 | IntakeManifoldPressureObdCommand press = new IntakeManifoldPressureObdCommand();
21 | runCmd(rpm);
22 | rpm.formatResult();
23 | double rpmV = rpm.getInt();
24 | runCmd(speed);
25 | speed.formatResult();
26 | double speedV = (double)speed.getInt();
27 | runCmd(temp);
28 | temp.formatResult();
29 | double tempV = temp.getInt() + 273.15; //convert to K
30 | runCmd(press);
31 | press.formatResult();
32 | double pressV = press.getInt();
33 | double imap = rpmV * pressV / tempV;
34 | double ve = 1.0;
35 | double ed = 1.0;
36 | if (connectThread != null) {
37 | ve = connectThread.getVolumetricEfficiency();
38 | ed = connectThread.getEngineDisplacement();
39 | }
40 | double mafV = (imap/120.0) * ve * ed * 28.97 / 8.314;
41 | String res = String.format("%.1f rpm, %.1f speed, %.1f temp, %.1f press, %.1f maf", rpmV, speedV, tempV, pressV, mafV);
42 | for (int i = 0; i < res.length(); i ++) {
43 | buff.add((byte)res.charAt(i));
44 | }
45 | fuelEcon = (14.7 * 6.17 * 454.0 * speedV * 0.621371) / (3600.0 * mafV);
46 | } catch (Exception e) {
47 | setError(e);
48 | }
49 | }
50 | public void runCmd(ObdCommand cmd) {
51 | cmd.setInputStream(in);
52 | cmd.setOutputStream(out);
53 | cmd.start();
54 | try {
55 | cmd.join();
56 | } catch (InterruptedException e) {
57 | setError(e);
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
25 |
26 |
27 |
28 |
29 |
30 |
32 |
33 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/awis/obd/command/FuelEconomyMAPObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | import awis.obd.config.ObdConfig;
4 |
5 |
6 | public class FuelEconomyMAPObdCommand extends FuelEconomyObdCommand {
7 |
8 | public static final double AIR_FUEL_RATIO = 14.64;
9 | public static final double FUEL_DENSITY_GRAMS_PER_LITER = 720.0;
10 |
11 | public FuelEconomyMAPObdCommand() {
12 | super("",ObdConfig.FUEL_ECON_MAP,"kml","mpg");
13 | }
14 | public FuelEconomyMAPObdCommand(FuelEconomyMAPObdCommand other) {
15 | super(other);
16 | }
17 | public void run() {
18 | try {
19 | EngineRPMObdCommand rpm = new EngineRPMObdCommand();
20 | AirIntakeTempObdCommand temp = new AirIntakeTempObdCommand();
21 | SpeedObdCommand speed = new SpeedObdCommand();
22 | CommandEquivRatioObdCommand equiv = new CommandEquivRatioObdCommand();
23 | IntakeManifoldPressureObdCommand press = new IntakeManifoldPressureObdCommand();
24 | runCmd(rpm);
25 | rpm.formatResult();
26 | double rpmV = rpm.getInt();
27 | runCmd(speed);
28 | speed.formatResult();
29 | double speedV = (double)speed.getInt();
30 | runCmd(temp);
31 | temp.formatResult();
32 | double tempV = temp.getInt() + 273.15; //convert to K
33 | runCmd(press);
34 | press.formatResult();
35 | double pressV = press.getInt();
36 | runCmd(equiv);
37 | equiv.formatResult();
38 | double equivV = equiv.getRatio();
39 | double imap = rpmV * pressV / tempV;
40 | double ve = 1.0;
41 | double ed = 1.0;
42 | if (connectThread != null) {
43 | ve = connectThread.getVolumetricEfficiency();
44 | ed = connectThread.getEngineDisplacement();
45 | }
46 | double mafV = (imap/120.0) * ve * ed * 28.97 / 8.314;
47 | String res = String.format("%.1f rpm, %.1f speed, %.1f temp, %.1f press, %.1f maf", rpmV, speedV, tempV, pressV, mafV);
48 | for (int i = 0; i < res.length(); i ++) {
49 | buff.add((byte)res.charAt(i));
50 | }
51 | fuelEcon = (14.7 * equivV * 6.17 * 454.0 * speedV * 0.621371) / (3600.0 * mafV);
52 | } catch (Exception e) {
53 | setError(e);
54 | }
55 | }
56 | public void runCmd(ObdCommand cmd) {
57 | cmd.setInputStream(in);
58 | cmd.setOutputStream(out);
59 | cmd.start();
60 | try {
61 | cmd.join();
62 | } catch (InterruptedException e) {
63 | setError(e);
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/res/xml/preferences.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
10 |
11 |
18 |
19 |
26 |
27 |
33 |
34 |
40 |
41 |
47 |
48 |
54 |
55 |
61 |
62 |
63 |
65 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/src/awis/obd/config/ObdConfig.java:
--------------------------------------------------------------------------------
1 | package awis.obd.config;
2 |
3 | import java.util.ArrayList;
4 |
5 | import awis.obd.command.AirIntakeTempObdCommand;
6 | import awis.obd.command.CommandEquivRatioObdCommand;
7 | import awis.obd.command.DtcNumberObdCommand;
8 | import awis.obd.command.EngineRPMObdCommand;
9 | import awis.obd.command.EngineRunTimeObdCommand;
10 | import awis.obd.command.FuelEconomyCommandedMAPObdCommand;
11 | import awis.obd.command.FuelEconomyMAPObdCommand;
12 | import awis.obd.command.FuelEconomyObdCommand;
13 | import awis.obd.command.FuelPressureObdCommand;
14 | import awis.obd.command.FuelTrimObdCommand;
15 | import awis.obd.command.IntakeManifoldPressureObdCommand;
16 | import awis.obd.command.MassAirFlowObdCommand;
17 | import awis.obd.command.ObdCommand;
18 | import awis.obd.command.PressureObdCommand;
19 | import awis.obd.command.SpeedObdCommand;
20 | import awis.obd.command.TempObdCommand;
21 | import awis.obd.command.ThrottleObdCommand;
22 | import awis.obd.command.TimingAdvanceObdCommand;
23 | import awis.obd.command.TroubleCodesObdCommand;
24 |
25 | public class ObdConfig {
26 |
27 | public final static String COOLANT_TEMP = "Coolant Temp";
28 | public final static String FUEL_ECON = "Fuel Economy";
29 | public final static String FUEL_ECON_MAP = "Fuel Economy MAP";
30 | public final static String RPM = "Engine RPM";
31 | public final static String RUN_TIME = "Engine Runtime";
32 | public final static String SPEED = "Vehicle Speed";
33 | public final static String AIR_TEMP = "Ambient Air Temp";
34 | public final static String INTAKE_TEMP = "Air Intake Temp";
35 |
36 | public static ArrayList getCommands() {
37 | ArrayList cmds = new ArrayList();
38 | cmds.add(new AirIntakeTempObdCommand());
39 | cmds.add(new IntakeManifoldPressureObdCommand());
40 | cmds.add(new PressureObdCommand("0133","Barometric Press","kPa","atm"));
41 | cmds.add(new TempObdCommand("0146",AIR_TEMP,"C","F"));
42 | cmds.add(new SpeedObdCommand());
43 | cmds.add(new ThrottleObdCommand());
44 | cmds.add(new EngineRPMObdCommand());
45 | cmds.add(new FuelPressureObdCommand());
46 | cmds.add(new TempObdCommand("0105",COOLANT_TEMP,"C","F"));
47 | cmds.add(new ThrottleObdCommand("0104","Engine Load","%"));
48 | cmds.add(new MassAirFlowObdCommand());
49 | cmds.add(new FuelEconomyObdCommand());
50 | cmds.add(new FuelEconomyMAPObdCommand());
51 | cmds.add(new FuelEconomyCommandedMAPObdCommand());
52 | cmds.add(new FuelTrimObdCommand());
53 | cmds.add(new FuelTrimObdCommand("0106","Short Term Fuel Trim","%"));
54 | cmds.add(new EngineRunTimeObdCommand());
55 | cmds.add(new CommandEquivRatioObdCommand());
56 | cmds.add(new TimingAdvanceObdCommand());
57 | cmds.add(new ObdCommand("03","Trouble Codes","",""));
58 | return cmds;
59 | }
60 | public static ArrayList getStaticCommands() {
61 | ArrayList cmds = new ArrayList();
62 | cmds.add(new DtcNumberObdCommand());
63 | cmds.add(new TroubleCodesObdCommand("03","Trouble Codes","",""));
64 | cmds.add(new ObdCommand("04","Reset Codes","",""));
65 | cmds.add(new ObdCommand("atz\ratz\ratz\r","Serial Reset atz","",""));
66 | cmds.add(new ObdCommand("atz\ratz\ratz\rate0","Serial Echo Off ate0","",""));
67 | cmds.add(new ObdCommand("ate1","Serial Echo On ate1","",""));
68 | cmds.add(new ObdCommand("atsp0","Reset Protocol astp0","",""));
69 | cmds.add(new ObdCommand("atspa2","Reset Protocol atspa2","",""));
70 | return cmds;
71 | }
72 | public static ArrayList getAllCommands() {
73 | ArrayList cmds = new ArrayList();
74 | cmds.addAll(getStaticCommands());
75 | cmds.addAll(getCommands());
76 | return cmds;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
12 |
15 |
18 |
23 |
27 |
33 |
34 |
35 |
39 |
42 |
47 |
53 |
58 |
59 |
74 |
75 |
80 |
83 |
86 |
89 |
92 |
95 |
96 |
97 |
101 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/src/awis/obd/command/ObdCommand.java:
--------------------------------------------------------------------------------
1 | package awis.obd.command;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.io.OutputStream;
6 | import java.util.ArrayList;
7 | import java.util.HashMap;
8 |
9 | import awis.obd.io.ObdConnectThread;
10 |
11 | public class ObdCommand extends Thread {
12 |
13 | /**
14 | * @uml.property name="in"
15 | */
16 | protected InputStream in = null;
17 | /**
18 | * @uml.property name="out"
19 | */
20 | protected OutputStream out = null;
21 | /**
22 | * @uml.property name="buff"
23 | * @uml.associationEnd multiplicity="(0 -1)" elementType="java.lang.Byte"
24 | */
25 | protected ArrayList buff = null;
26 | /**
27 | * @uml.property name="cmd"
28 | */
29 | protected String cmd = null;
30 | /**
31 | * @uml.property name="desc"
32 | */
33 | protected String desc = null;
34 | /**
35 | * @uml.property name="resType"
36 | */
37 | protected String resType = null;
38 | /**
39 | * @uml.property name="error"
40 | */
41 | protected Exception error;
42 | /**
43 | * @uml.property name="rawValue"
44 | */
45 | protected Object rawValue = null;
46 | /**
47 | * @uml.property name="data"
48 | * @uml.associationEnd qualifier="constant:java.lang.String java.lang.Double"
49 | */
50 | protected HashMap data = null;
51 | /**
52 | * @uml.property name="connectThread"
53 | * @uml.associationEnd inverse="cmds:awis.obd.io.ObdConnectThread"
54 | */
55 | protected ObdConnectThread connectThread = null;
56 | /**
57 | * @uml.property name="impType"
58 | */
59 | protected String impType = null;
60 |
61 | public ObdCommand(String cmd, String desc, String resType, String impType) {
62 | this.cmd = cmd;
63 | this.desc = desc;
64 | this.resType = resType;
65 | this.buff = new ArrayList();
66 | this.impType = impType;
67 | }
68 | /**
69 | * @param thread
70 | * @uml.property name="connectThread"
71 | */
72 | public void setConnectThread(ObdConnectThread thread) {
73 | this.connectThread = thread;
74 | }
75 | public boolean isImperial() {
76 | if (connectThread != null && connectThread.getImperialUnits()) {
77 | return true;
78 | }
79 | return false;
80 | }
81 | public ObdCommand(ObdCommand other) {
82 | this(other.cmd, other.desc, other.resType, other.impType);
83 | }
84 | public void setInputStream(InputStream in) {
85 | this.in = in;
86 | }
87 | public void setOutputStream(OutputStream out) {
88 | this.out = out;
89 | }
90 | public void run() {
91 | sendCmd(cmd);
92 | readResult();
93 | }
94 | public void setDataMap(HashMap data) {
95 | this.data = data;
96 | }
97 | protected void sendCmd(String cmd) {
98 | try {
99 | cmd += "\r\n";
100 | out.write(cmd.getBytes());
101 | out.flush();
102 | } catch (Exception e) {
103 | // TODO: handle exception
104 | }
105 | }
106 | protected void readResult() {
107 | byte c = 0;
108 | this.buff.clear();
109 | try {
110 | while ((char)(c = (byte)in.read()) != '>') {
111 | buff.add(c);
112 | }
113 | } catch (IOException e) {
114 | }
115 | }
116 | public String getResult() {
117 | return new String(getByteArray());
118 | }
119 | public byte[] getByteArray() {
120 | byte[] data = new byte[this.buff.size()];
121 | for (int i = 0; i < this.buff.size(); i++) {
122 | data[i] = this.buff.get(i);
123 | }
124 | return data;
125 | }
126 | public String formatResult() {
127 | String res = getResult();
128 | String[] ress = res.split("\r");
129 | res = ress[0].replace(" ","");
130 | return res;
131 | }
132 | /**
133 | * @return
134 | * @uml.property name="in"
135 | */
136 | public InputStream getIn() {
137 | return in;
138 | }
139 | /**
140 | * @return
141 | * @uml.property name="out"
142 | */
143 | public OutputStream getOut() {
144 | return out;
145 | }
146 | public ArrayList getBuff() {
147 | return buff;
148 | }
149 | /**
150 | * @return
151 | * @uml.property name="cmd"
152 | */
153 | public String getCmd() {
154 | return cmd;
155 | }
156 | /**
157 | * @return
158 | * @uml.property name="desc"
159 | */
160 | public String getDesc() {
161 | return desc;
162 | }
163 | /**
164 | * @return
165 | * @uml.property name="resType"
166 | */
167 | public String getResType() {
168 | return resType;
169 | }
170 | /**
171 | * @param e
172 | * @uml.property name="error"
173 | */
174 | public void setError(Exception e) {
175 | error = e;
176 | }
177 | /**
178 | * @return
179 | * @uml.property name="error"
180 | */
181 | public Exception getError() {
182 | return error;
183 | }
184 | /**
185 | * @return
186 | * @uml.property name="rawValue"
187 | */
188 | public Object getRawValue() {
189 | return rawValue;
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/src/awis/obd/activity/ObdReaderCommandActivity.java:
--------------------------------------------------------------------------------
1 | package awis.obd.activity;
2 |
3 | import java.util.ArrayList;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 | import java.util.UUID;
7 |
8 | import awis.obd.activity.R;
9 | import awis.obd.command.ObdCommand;
10 | import awis.obd.command.ObdMultiCommand;
11 | import awis.obd.config.ObdConfig;
12 | import awis.obd.io.ObdCommandConnectThread;
13 | import awis.obd.io.ObdConnectThread;
14 | import android.app.Activity;
15 | import android.bluetooth.BluetoothAdapter;
16 | import android.bluetooth.BluetoothDevice;
17 | import android.content.SharedPreferences;
18 | import android.os.Bundle;
19 | import android.os.Handler;
20 | import android.preference.PreferenceManager;
21 | import android.view.View;
22 | import android.widget.AdapterView;
23 | import android.widget.ArrayAdapter;
24 | import android.widget.Spinner;
25 | import android.widget.TextView;
26 | import android.widget.Toast;
27 | import android.widget.AdapterView.OnItemSelectedListener;
28 |
29 | public class ObdReaderCommandActivity extends Activity implements
30 | OnItemSelectedListener {
31 |
32 |
33 | final private ArrayList commands = ObdConfig.getAllCommands();
34 |
35 | private Map cmdMap = null;
36 | protected static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
37 | private Handler handler = null;
38 | private SharedPreferences prefs = null;
39 | private final static String NO_SELECTION_TXT = "Choose Command to Run...";
40 |
41 | public void onCreate(Bundle savedInstance) {
42 | super.onCreate(savedInstance);
43 | prefs = PreferenceManager
44 | .getDefaultSharedPreferences(ObdReaderCommandActivity.this);
45 | setContentView(R.layout.command);
46 | Spinner cmdSpin = (Spinner) findViewById(R.id.command_spinner);
47 | cmdSpin.setOnItemSelectedListener(this);
48 | cmdMap = new HashMap();
49 | ArrayList cmdStrs = new ArrayList();
50 | cmdStrs.add(NO_SELECTION_TXT);
51 | String[] configCmdStrs = ObdReaderConfigActivity
52 | .getReaderConfigCommands(prefs);
53 | ObdMultiCommand configCmd = new ObdMultiCommand(configCmdStrs,
54 | "Configure Reader", "string", "string");
55 | cmdMap.put(configCmd.getDesc(), configCmd);
56 | cmdStrs.add(configCmd.getDesc());
57 | for (ObdCommand cmd : commands) {
58 | cmdMap.put(cmd.getDesc(), cmd);
59 | cmdStrs.add(cmd.getDesc());
60 | }
61 | ArrayAdapter adapt = new ArrayAdapter(this,
62 | android.R.layout.simple_spinner_item, cmdStrs);
63 | cmdSpin.setAdapter(adapt);
64 | handler = new Handler();
65 | }
66 |
67 | public void onItemSelected(AdapterView> arg0, View arg1, int arg2,
68 | long arg3) {
69 | Spinner cmdSpin = (Spinner) findViewById(R.id.command_spinner);
70 | String cmdDesc = cmdSpin.getSelectedItem().toString();
71 | if (NO_SELECTION_TXT.equals(cmdDesc)) {
72 | return;
73 | }
74 | ObdCommand cmd = cmdMap.get(cmdDesc);
75 | ObdReaderCommandActivityWorkerThread worker = null;
76 | try {
77 | worker = new ObdReaderCommandActivityWorkerThread(
78 | ObdConnectThread.getCopy(cmd));
79 | } catch (Exception e) {
80 | Toast.makeText(this, "Error copying command: " + e.getMessage(),
81 | Toast.LENGTH_LONG).show();
82 | return;
83 | }
84 | worker.start();
85 | cmdSpin.setSelection(0);
86 | }
87 |
88 | public void onNothingSelected(AdapterView> arg0) {
89 | }
90 |
91 | public void showMessage(final String message) {
92 | final Activity act = this;
93 | handler.post(new Runnable() {
94 | public void run() {
95 | Toast.makeText(act, message, Toast.LENGTH_LONG).show();
96 | }
97 | });
98 | }
99 |
100 | private void setText(final String value, final boolean clear) {
101 | handler.post(new Runnable() {
102 | public void run() {
103 | TextView txtView = (TextView) findViewById(R.id.command_result_text);
104 | String curr = (String) txtView.getText();
105 | if (curr == null || clear || "".equals(curr)) {
106 | curr = value;
107 | } else {
108 | curr = curr + "\n" + value;
109 | }
110 | txtView.setText(curr);
111 | }
112 | });
113 | }
114 |
115 | public void logMsg(final String msg) {
116 | setText(msg, false);
117 | }
118 |
119 | private class ObdReaderCommandActivityWorkerThread extends Thread {
120 |
121 | ObdCommand cmd = null;
122 |
123 | private ObdReaderCommandActivityWorkerThread(ObdCommand cmd) {
124 | this.cmd = cmd;
125 | }
126 |
127 | public void run() {
128 | String devString = prefs.getString(
129 | ObdReaderConfigActivity.BLUETOOTH_LIST_KEY, null);
130 | final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter
131 | .getDefaultAdapter();
132 | if (mBluetoothAdapter == null) {
133 | showMessage("This device does not support bluetooth");
134 | return;
135 | }
136 | if (devString == null || "".equals(devString)) {
137 | showMessage("No bluetooth device selected");
138 | return;
139 | }
140 | BluetoothDevice dev = mBluetoothAdapter.getRemoteDevice(devString);
141 | double ve = ObdReaderConfigActivity.getVolumetricEfficieny(prefs);
142 | double ed = ObdReaderConfigActivity.getEngineDisplacement(prefs);
143 | boolean imperialUnits = prefs.getBoolean(
144 | ObdReaderConfigActivity.IMPERIAL_UNITS_KEY, false);
145 | final ObdCommandConnectThread thread = new ObdCommandConnectThread(
146 | dev, ObdReaderCommandActivity.this, cmd, ed, ve,
147 | imperialUnits);
148 | thread.setVolumetricEfficiency(ve);
149 | thread.setEngineDisplacement(ed);
150 | setText(String.format("Running %s...", cmd.getDesc()), true);
151 | try {
152 | thread.start();
153 | thread.join();
154 | } catch (Exception e1) {
155 | showMessage("Error getting connection: " + e1.getMessage());
156 | }
157 | String res = null;
158 | if (!thread.getResults().containsKey(cmd.getDesc())) {
159 | res = "Didn't get a result.";
160 | } else {
161 | res = thread.getResults().get(cmd.getDesc());
162 | }
163 | logMsg("Formated result: " + res);
164 | }
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/src/awis/obd/io/ObdReaderService.java:
--------------------------------------------------------------------------------
1 | package awis.obd.io;
2 |
3 | import java.io.PrintWriter;
4 | import java.io.StringWriter;
5 | import java.util.ArrayList;
6 | import java.util.Map;
7 |
8 | import awis.obd.activity.ObdReaderConfigActivity;
9 | import awis.obd.activity.R;
10 | import awis.obd.command.ObdCommand;
11 |
12 | import android.app.Notification;
13 | import android.app.NotificationManager;
14 | import android.app.PendingIntent;
15 | import android.app.Service;
16 | import android.bluetooth.BluetoothAdapter;
17 | import android.bluetooth.BluetoothDevice;
18 | import android.content.Context;
19 | import android.content.Intent;
20 | import android.content.SharedPreferences;
21 | import android.location.LocationManager;
22 | import android.os.Binder;
23 | import android.os.IBinder;
24 | import android.preference.PreferenceManager;
25 | import android.widget.Toast;
26 |
27 | public class ObdReaderService extends Service {
28 |
29 | private ObdConnectThread connectThread = null;
30 | private final IBinder binder = new ObdReaderServiceBinder();
31 | private NotificationManager notifyMan = null;
32 | private Context context = null;
33 | private Intent notificationIntent = null;
34 | private PendingIntent contentIntent = null;
35 | public static final int COMMAND_ERROR_NOTIFY = 2;
36 | public static final int CONNECT_ERROR_NOTIFY = 3;
37 | public static final int OBD_SERVICE_RUNNING_NOTIFY = 4;
38 | public static final int OBD_SERVICE_ERROR_NOTIFY = 5;
39 |
40 | public void onCreate() {
41 | super.onCreate();
42 | notifyMan = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
43 | context = getApplicationContext();
44 | notificationIntent = new Intent(this, ObdReaderService.class);
45 | contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
46 | }
47 | public void onDestroy() {
48 | super.onDestroy();
49 | stopService();
50 | stopSelf();
51 | }
52 | public boolean isRunning() {
53 | if (connectThread == null) {
54 | return false;
55 | }
56 | return connectThread.isAlive();
57 | }
58 | public IBinder onBind(Intent intent) {
59 | return binder;
60 | }
61 | public boolean startService() {
62 | if (connectThread != null && connectThread.isAlive()) {
63 | return true;
64 | }
65 | SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
66 | String devString = prefs.getString(ObdReaderConfigActivity.BLUETOOTH_LIST_KEY, null);
67 | boolean uploadEnabled = prefs.getBoolean(ObdReaderConfigActivity.UPLOAD_DATA_KEY,false);
68 | String uploadUrl = null;
69 | if (uploadEnabled) {
70 | uploadUrl = prefs.getString(ObdReaderConfigActivity.UPLOAD_URL_KEY, null);
71 | }
72 | final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
73 | if (mBluetoothAdapter == null) {
74 | Toast.makeText(this, "This device does not support bluetooth", Toast.LENGTH_LONG).show();
75 | stopSelf();
76 | return false;
77 | }
78 | if (devString == null || "".equals(devString)) {
79 | Toast.makeText(this, "No bluetooth device selected", Toast.LENGTH_LONG).show();
80 | stopSelf();
81 | return false;
82 | }
83 | LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
84 | if (locationManager == null) {
85 | Toast.makeText(this, "This device does not support GPS", Toast.LENGTH_LONG).show();
86 | stopSelf();
87 | return false;
88 | }
89 | int period = ObdReaderConfigActivity.getUpdatePeriod(prefs);
90 | double ve = ObdReaderConfigActivity.getVolumetricEfficieny(prefs);
91 | double ed = ObdReaderConfigActivity.getEngineDisplacement(prefs);
92 | boolean imperialUnits = prefs.getBoolean(ObdReaderConfigActivity.IMPERIAL_UNITS_KEY, false);
93 | boolean gps = prefs.getBoolean(ObdReaderConfigActivity.ENABLE_GPS_KEY, false);
94 | ArrayList cmds = ObdReaderConfigActivity.getObdCommands(prefs);
95 | BluetoothDevice dev = mBluetoothAdapter.getRemoteDevice(devString);
96 | connectThread = new ObdConnectThread(dev,locationManager,this,uploadUrl,period,ed,ve,imperialUnits,gps,cmds);
97 | connectThread.setEngineDisplacement(ed);
98 | connectThread.setVolumetricEfficiency(ve);
99 | new ObdReaderServiceWorkerThread(connectThread).start();
100 | return true;
101 | }
102 | public boolean stopService() {
103 | if (connectThread == null) {
104 | return true;
105 | }
106 | while (connectThread.isAlive()) {
107 | try {
108 | connectThread.cancel();
109 | connectThread.join(300);
110 | } catch (InterruptedException e) {
111 | StringWriter strw = new StringWriter();
112 | PrintWriter ptrw = new PrintWriter(strw);
113 | e.printStackTrace(ptrw);
114 | notifyMessage(e.getMessage(),strw.toString(), OBD_SERVICE_ERROR_NOTIFY);
115 | }
116 | }
117 | connectThread.close();
118 | stopSelf();
119 | return true;
120 | }
121 | public void notifyMessage(String msg, String longMsg, int notifyId) {
122 | long when = System.currentTimeMillis();
123 | Notification notification = new Notification(android.R.drawable.stat_notify_error, msg, when);
124 | notification.setLatestEventInfo(context, msg, longMsg, contentIntent);
125 | notifyMan.notify(notifyId, notification);
126 | }
127 | public Map getDataMap() {
128 | if (connectThread != null) {
129 | return connectThread.getResults();
130 | }
131 | return null;
132 | }
133 | public class ObdReaderServiceBinder extends Binder {
134 | ObdReaderService getService() {
135 | return ObdReaderService.this;
136 | }
137 | }
138 | private class ObdReaderServiceWorkerThread extends Thread {
139 |
140 | ObdConnectThread t = null;
141 | public ObdReaderServiceWorkerThread(ObdConnectThread t) {
142 | this.t = t;
143 | }
144 | public void run() {
145 | try {
146 | t.start();
147 | long when = System.currentTimeMillis();
148 | Notification notification = new Notification(R.drawable.car, "OBD Service Running", when);
149 | notification.setLatestEventInfo(context, "OBD Service Running", "", contentIntent);
150 | notification.flags |= Notification.FLAG_NO_CLEAR;
151 | notification.flags |= Notification.FLAG_ONGOING_EVENT;
152 | notifyMan.notify(OBD_SERVICE_RUNNING_NOTIFY, notification);
153 | t.join();
154 | } catch (Exception e) {
155 | } finally {
156 | notifyMan.cancel(OBD_SERVICE_RUNNING_NOTIFY);
157 | stopSelf();
158 | }
159 | }
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/src/awis/obd/activity/ObdReaderConfigActivity.java:
--------------------------------------------------------------------------------
1 | package awis.obd.activity;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Set;
5 |
6 | import awis.obd.activity.R;
7 | import awis.obd.command.ObdCommand;
8 | import awis.obd.config.ObdConfig;
9 | import android.app.Activity;
10 | import android.bluetooth.BluetoothAdapter;
11 | import android.bluetooth.BluetoothDevice;
12 | import android.content.SharedPreferences;
13 | import android.os.Bundle;
14 | import android.preference.CheckBoxPreference;
15 | import android.preference.EditTextPreference;
16 | import android.preference.ListPreference;
17 | import android.preference.Preference;
18 | import android.preference.PreferenceActivity;
19 | import android.preference.PreferenceScreen;
20 | import android.preference.Preference.OnPreferenceChangeListener;
21 | import android.preference.Preference.OnPreferenceClickListener;
22 | import android.widget.Toast;
23 |
24 | public class ObdReaderConfigActivity extends PreferenceActivity implements OnPreferenceChangeListener {
25 |
26 | public static final String BLUETOOTH_LIST_KEY = "bluetooth_list_preference";
27 | public static final String UPLOAD_URL_KEY = "upload_url_preference";
28 | public static final String UPLOAD_DATA_KEY = "upload_data_preference";
29 | public static final String UPDATE_PERIOD_KEY = "update_period_preference";
30 | public static final String VEHICLE_ID_KEY = "vehicle_id_preference";
31 | public static final String ENGINE_DISPLACEMENT_KEY = "engine_displacement_preference";
32 | public static final String VOLUMETRIC_EFFICIENCY_KEY = "volumetric_efficiency_preference";
33 | public static final String IMPERIAL_UNITS_KEY = "imperial_units_preference";
34 | public static final String COMMANDS_SCREEN_KEY = "obd_commands_screen";
35 | public static final String ENABLE_GPS_KEY = "enable_gps_preference";
36 | public static final String MAX_FUEL_ECON_KEY = "max_fuel_econ_preference";
37 | public static final String CONFIG_READER_KEY = "reader_config_preference";
38 |
39 | public void onCreate(Bundle savedInstanceState) {
40 | super.onCreate(savedInstanceState);
41 | addPreferencesFromResource(R.xml.preferences);
42 | ArrayList pairedDeviceStrings = new ArrayList();
43 | ArrayList vals = new ArrayList();
44 | ListPreference listPref = (ListPreference) getPreferenceScreen().findPreference(BLUETOOTH_LIST_KEY);
45 | String[] prefKeys = new String[]{ENGINE_DISPLACEMENT_KEY,VOLUMETRIC_EFFICIENCY_KEY,UPDATE_PERIOD_KEY,MAX_FUEL_ECON_KEY};
46 | for (String prefKey:prefKeys) {
47 | EditTextPreference txtPref = (EditTextPreference) getPreferenceScreen().findPreference(prefKey);
48 | txtPref.setOnPreferenceChangeListener(this);
49 | }
50 | final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
51 | if (mBluetoothAdapter == null) {
52 | listPref.setEntries(pairedDeviceStrings.toArray(new CharSequence[0]));
53 | listPref.setEntryValues(vals.toArray(new CharSequence[0]));
54 | return;
55 | }
56 | final Activity thisAct = this;
57 | listPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
58 | @SuppressWarnings("unused")
59 | public boolean onPreferenceClick(Preference preference) {
60 | if (mBluetoothAdapter == null) {
61 | Toast.makeText(thisAct,"This device does not support bluetooth", Toast.LENGTH_LONG);
62 | return false;
63 | }
64 | return true;
65 | }
66 | });
67 | Set pairedDevices = mBluetoothAdapter.getBondedDevices();
68 | if (pairedDevices.size() > 0) {
69 | for (BluetoothDevice device : pairedDevices) {
70 | pairedDeviceStrings.add(device.getName() + "\n" + device.getAddress());
71 | vals.add(device.getAddress());
72 | }
73 | }
74 | listPref.setEntries(pairedDeviceStrings.toArray(new CharSequence[0]));
75 | listPref.setEntryValues(vals.toArray(new CharSequence[0]));
76 | ArrayList cmds = ObdConfig.getCommands();
77 | PreferenceScreen cmdScr = (PreferenceScreen) getPreferenceScreen().findPreference(COMMANDS_SCREEN_KEY);
78 | for (int i = 0; i < cmds.size(); i++) {
79 | ObdCommand cmd = cmds.get(i);
80 | CheckBoxPreference cpref = new CheckBoxPreference(this);
81 | cpref.setTitle(cmd.getDesc());
82 | cpref.setKey(cmd.getDesc());
83 | cpref.setChecked(true);
84 | cmdScr.addPreference(cpref);
85 | }
86 | }
87 | public boolean onPreferenceChange(Preference preference, Object newValue) {
88 | if (UPDATE_PERIOD_KEY.equals(preference.getKey()) ||
89 | VOLUMETRIC_EFFICIENCY_KEY.equals(preference.getKey()) ||
90 | ENGINE_DISPLACEMENT_KEY.equals(preference.getKey()) ||
91 | MAX_FUEL_ECON_KEY.equals(preference.getKey())) {
92 | try {
93 | Double.parseDouble(newValue.toString());
94 | return true;
95 | } catch (Exception e) {
96 | Toast.makeText(this,"Couldn't parse '" + newValue.toString() + "' as a number.",Toast.LENGTH_LONG).show();
97 | }
98 | }
99 | return false;
100 | }
101 | public static int getUpdatePeriod(SharedPreferences prefs) {
102 | String periodString = prefs.getString(ObdReaderConfigActivity.UPDATE_PERIOD_KEY, "4");
103 | int period = 4000;
104 | try {
105 | period = Integer.parseInt(periodString) * 1000;
106 | } catch (Exception e) {
107 | }
108 | if (period <= 0) {
109 | period = 250;
110 | }
111 | return period;
112 | }
113 | public static double getVolumetricEfficieny(SharedPreferences prefs) {
114 | String veString = prefs.getString(ObdReaderConfigActivity.VOLUMETRIC_EFFICIENCY_KEY, ".85");
115 | double ve = 0.85;
116 | try {
117 | ve = Double.parseDouble(veString);
118 | } catch (Exception e) {
119 | }
120 | return ve;
121 | }
122 | public static double getEngineDisplacement(SharedPreferences prefs) {
123 | String edString = prefs.getString(ObdReaderConfigActivity.ENGINE_DISPLACEMENT_KEY, "1.6");
124 | double ed = 1.6;
125 | try {
126 | ed = Double.parseDouble(edString);
127 | } catch (Exception e) {
128 | }
129 | return ed;
130 | }
131 | public static ArrayList getObdCommands(SharedPreferences prefs) {
132 | ArrayList cmds = ObdConfig.getCommands();
133 | ArrayList ucmds = new ArrayList();
134 | for (int i = 0; i < cmds.size(); i++) {
135 | ObdCommand cmd = cmds.get(i);
136 | boolean selected = prefs.getBoolean(cmd.getDesc(), true);
137 | if (selected) {
138 | ucmds.add(cmd);
139 | }
140 | }
141 | return ucmds;
142 | }
143 | public static double getMaxFuelEconomy(SharedPreferences prefs) {
144 | String maxStr = prefs.getString(ObdReaderConfigActivity.MAX_FUEL_ECON_KEY, "70");
145 | double max = 70;
146 | try {
147 | max = Double.parseDouble(maxStr);
148 | } catch (Exception e) {
149 | }
150 | return max;
151 | }
152 | public static String[] getReaderConfigCommands(SharedPreferences prefs) {
153 | String cmdsStr = prefs.getString(CONFIG_READER_KEY, "atsp0\natz");
154 | String[] cmds = cmdsStr.split("\n");
155 | return cmds;
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/src/awis/obd/io/ObdConnectThread.java:
--------------------------------------------------------------------------------
1 | package awis.obd.io;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.io.OutputStream;
6 | import java.io.PrintWriter;
7 | import java.io.StringWriter;
8 | import java.lang.reflect.InvocationTargetException;
9 | import java.util.ArrayList;
10 | import java.util.HashMap;
11 | import java.util.Map;
12 | import java.util.UUID;
13 | import awis.obd.command.ObdCommand;
14 | import android.bluetooth.BluetoothDevice;
15 | import android.bluetooth.BluetoothSocket;
16 | import android.location.Location;
17 | import android.location.LocationListener;
18 | import android.location.LocationManager;
19 | import android.os.Bundle;
20 |
21 | public class ObdConnectThread extends Thread implements LocationListener {
22 |
23 | /**
24 | * @uml.property name="dev"
25 | * @uml.associationEnd multiplicity="(1 1)"
26 | */
27 | protected BluetoothDevice dev = null;
28 | /**
29 | * @uml.property name="sock"
30 | * @uml.associationEnd
31 | */
32 | protected BluetoothSocket sock = null;
33 | /**
34 | * @uml.property name="stop"
35 | */
36 | protected boolean stop = false;
37 | protected static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
38 | /**
39 | * @uml.property name="in"
40 | */
41 | protected InputStream in = null;
42 | /**
43 | * @uml.property name="out"
44 | */
45 | protected OutputStream out = null;
46 | /**
47 | * @uml.property name="cmds"
48 | * @uml.associationEnd multiplicity="(0 -1)" inverse="connectThread:awis.obd.command.ObdCommand"
49 | */
50 | protected ArrayList cmds = null;
51 | /**
52 | * @uml.property name="results"
53 | * @uml.associationEnd qualifier="constant:java.lang.String java.lang.String"
54 | */
55 | protected HashMap results = null;
56 | /**
57 | * @uml.property name="data"
58 | * @uml.associationEnd qualifier="constant:java.lang.String java.lang.Double"
59 | */
60 | protected HashMap data = null;
61 | /**
62 | * @uml.property name="updateCycle"
63 | */
64 | protected int updateCycle = 4000;
65 | /**
66 | * @uml.property name="service"
67 | * @uml.associationEnd multiplicity="(1 1)" inverse="connectThread:awis.obd.io.ObdReaderService"
68 | */
69 | protected ObdReaderService service = null;
70 | /**
71 | * @uml.property name="uploadUrl"
72 | */
73 | protected String uploadUrl = null;
74 | /**
75 | * @uml.property name="currentLocation"
76 | * @uml.associationEnd
77 | */
78 | protected Location currentLocation = null;
79 | /**
80 | * @uml.property name="locationManager"
81 | * @uml.associationEnd multiplicity="(1 1)"
82 | */
83 | protected LocationManager locationManager = null;
84 | /**
85 | * @uml.property name="engineDisplacement"
86 | */
87 | protected double engineDisplacement = 1.0;
88 | /**
89 | * @uml.property name="volumetricEfficiency"
90 | */
91 | protected double volumetricEfficiency = 1.0;
92 | /**
93 | * @uml.property name="imperialUnits"
94 | */
95 | protected boolean imperialUnits = false;
96 |
97 | public ObdConnectThread(BluetoothDevice dev,
98 | LocationManager locationManager, final ObdReaderService service,
99 | String uploadUrl, int updateCycle, double engineDisplacement,
100 | double volumetricEfficiency, boolean imperialUnits,
101 | boolean enableGps, ArrayList cmds) {
102 | this.dev = dev;
103 | this.cmds = cmds;
104 | this.updateCycle = updateCycle;
105 | this.service = service;
106 | this.uploadUrl = uploadUrl;
107 | this.locationManager = locationManager;
108 | if (locationManager != null && enableGps) {
109 | this.locationManager.requestLocationUpdates(
110 | LocationManager.GPS_PROVIDER, 0, 0.0f, this);
111 | }
112 | results = new HashMap();
113 | data = new HashMap();
114 | this.volumetricEfficiency = volumetricEfficiency;
115 | this.engineDisplacement = engineDisplacement;
116 | this.imperialUnits = imperialUnits;
117 | }
118 |
119 | protected void startDevice() throws IOException, InterruptedException {
120 | sock = this.dev.createRfcommSocketToServiceRecord(MY_UUID);
121 | sock.connect();
122 | in = sock.getInputStream();
123 | out = sock.getOutputStream();
124 | while (!stop) {
125 | ObdCommand echoOff = new ObdCommand("ate0", "echo off", "string",
126 | "string");
127 | String result = runCommand(echoOff).replace(" ", "");
128 | if (result != null && result.contains("OK")) {
129 | break;
130 | }
131 | Thread.sleep(1500);
132 | }
133 | }
134 |
135 | public void run() {
136 | try {
137 | startDevice();
138 | int cmdSize = cmds.size();
139 | for (int i = 0; i < cmdSize; i++) {
140 | String desc = cmds.get(i).getDesc();
141 | results.put(desc, "--");
142 | data.put(desc, -9999);
143 | }
144 | for (int i = 0; !stop; i = ((i + 1) % cmdSize)) {
145 | if (i == 0) {
146 | long obsTime = System.currentTimeMillis() / 1000;
147 | results.put("Obs Time", Long.toString(obsTime));
148 | data.put("Obs Time", obsTime);
149 |
150 | Thread.sleep(updateCycle);
151 | }
152 | ObdCommand cmd = cmds.get(i);
153 | try {
154 | cmd = getCopy(cmd); // make a copy because thread can only
155 | // run once
156 | String desc = cmd.getDesc();
157 | String result = runCommand(cmd);
158 | results.put(desc, result);
159 | data.put(desc, cmd.getRawValue());
160 | } catch (Exception e) {
161 | results.put(cmd.getDesc(), "--");
162 | if (!stop) {
163 | service.notifyMessage("Error running " + cmd.getDesc(),
164 | e.getMessage(),
165 | ObdReaderService.COMMAND_ERROR_NOTIFY);
166 | }
167 | }
168 | }
169 | } catch (IOException e) {
170 | service.notifyMessage("Bluetooth Connection Error", e.getMessage(),
171 | ObdReaderService.CONNECT_ERROR_NOTIFY);
172 | } catch (Exception e) {
173 | service.notifyMessage(e.getMessage(), e.toString(),
174 | ObdReaderService.OBD_SERVICE_ERROR_NOTIFY);
175 | } finally {
176 | close();
177 | }
178 | }
179 |
180 | public static ObdCommand getCopy(ObdCommand cmd)
181 | throws IllegalArgumentException, SecurityException,
182 | InstantiationException, IllegalAccessException,
183 | InvocationTargetException, NoSuchMethodException {
184 | return cmd.getClass().getConstructor(cmd.getClass()).newInstance(cmd);
185 | }
186 |
187 | public String runCommand(ObdCommand cmd) throws InterruptedException {
188 | cmd.setInputStream(in);
189 | cmd.setOutputStream(out);
190 | cmd.setDataMap(data);
191 | cmd.setConnectThread(this);
192 | cmd.start();
193 | while (!stop) {
194 | cmd.join(300);
195 | if (!cmd.isAlive()) {
196 | break;
197 | }
198 | }
199 | return cmd.formatResult();
200 | }
201 |
202 | public ArrayList getCmds() {
203 | return cmds;
204 | }
205 |
206 | public synchronized Map getResults() {
207 | if (currentLocation != null) {
208 | double lat = currentLocation.getLatitude();
209 | double lon = currentLocation.getLongitude();
210 | int speed = (int) currentLocation.getSpeed();
211 | long gtime = currentLocation.getTime() / 1000;
212 | results.put("Latitude", String.format("%.5f", lat));
213 | results.put("Longitude", String.format("%.5f", lon));
214 | results.put("GPS Speed", String.format("%d m/s", speed));
215 | results.put("GPS Time", Long.toString(gtime));
216 | data.put("Latitude", lat);
217 | data.put("Longitude", lon);
218 | data.put("GPS Speed", speed);
219 | data.put("GPS Time", gtime);
220 | }
221 | return results;
222 | }
223 |
224 | public void cancel() {
225 | stop = true;
226 | }
227 |
228 | public void close() {
229 | try {
230 | locationManager.removeUpdates(this);
231 | } catch (Exception e) {
232 | }
233 | try {
234 | stop = true;
235 | sock.close();
236 | } catch (Exception e) {
237 | }
238 | }
239 |
240 | public String getStackTrace(Exception e) {
241 | StringWriter strw = new StringWriter();
242 | PrintWriter ptrw = new PrintWriter(strw);
243 | e.printStackTrace(ptrw);
244 | return strw.toString();
245 | }
246 |
247 | public void onLocationChanged(Location location) {
248 | currentLocation = location;
249 | }
250 |
251 | public void onProviderDisabled(String provider) {
252 | service.notifyMessage("GPS Unavailable",
253 | "GPS_PROVIDER disabled, please enable gps in your settings.",
254 | ObdReaderService.OBD_SERVICE_ERROR_NOTIFY);
255 | }
256 |
257 | public void onProviderEnabled(String provider) {
258 | }
259 |
260 | public void onStatusChanged(String provider, int status, Bundle extras) {
261 | }
262 |
263 | /**
264 | * @param ve
265 | * @uml.property name="volumetricEfficiency"
266 | */
267 | public void setVolumetricEfficiency(double ve) {
268 | this.volumetricEfficiency = ve;
269 | }
270 |
271 | /**
272 | * @param ed
273 | * @uml.property name="engineDisplacement"
274 | */
275 | public void setEngineDisplacement(double ed) {
276 | this.engineDisplacement = ed;
277 | }
278 |
279 | /**
280 | * @return
281 | * @uml.property name="volumetricEfficiency"
282 | */
283 | public double getVolumetricEfficiency() {
284 | return volumetricEfficiency;
285 | }
286 |
287 | /**
288 | * @return
289 | * @uml.property name="engineDisplacement"
290 | */
291 | public double getEngineDisplacement() {
292 | return engineDisplacement;
293 | }
294 |
295 | public boolean getImperialUnits() {
296 | return imperialUnits;
297 | }
298 | }
--------------------------------------------------------------------------------
/src/awis/obd/activity/ObdReaderMainActivity.java:
--------------------------------------------------------------------------------
1 | package awis.obd.activity;
2 |
3 | import java.util.Arrays;
4 | import java.util.HashMap;
5 | import java.util.List;
6 | import java.util.Map;
7 | import java.util.Set;
8 |
9 | import awis.obd.activity.R;
10 | import awis.obd.command.ObdCommand;
11 | import awis.obd.config.ObdConfig;
12 | import awis.obd.drawable.CoolantGaugeView;
13 | import awis.obd.io.ObdReaderService;
14 | import awis.obd.io.ObdReaderServiceConnection;
15 |
16 | import android.app.Activity;
17 | import android.app.AlertDialog;
18 | import android.app.Dialog;
19 | import android.bluetooth.BluetoothAdapter;
20 | import android.content.Context;
21 | import android.content.Intent;
22 | import android.content.SharedPreferences;
23 | import android.graphics.Color;
24 | import android.hardware.Sensor;
25 | import android.hardware.SensorEvent;
26 | import android.hardware.SensorEventListener;
27 | import android.hardware.SensorManager;
28 | import android.location.LocationManager;
29 | import android.os.Bundle;
30 | import android.os.Handler;
31 | import android.os.PowerManager;
32 | import android.preference.PreferenceManager;
33 | import android.view.Gravity;
34 | import android.view.Menu;
35 | import android.view.MenuItem;
36 | import android.view.ViewGroup;
37 | import android.view.ViewGroup.LayoutParams;
38 | import android.view.ViewGroup.MarginLayoutParams;
39 | import android.widget.TableLayout;
40 | import android.widget.TableRow;
41 | import android.widget.TextView;
42 | import android.widget.Toast;
43 |
44 | public class ObdReaderMainActivity extends Activity {
45 | static final int NO_BLUETOOTH_ID = 0;
46 | static final int NO_GPS_ID = 1;
47 | static final int START_LIVE_DATA = 1;
48 | static final int STOP_LIVE_DATA = 2;
49 | static final int SETTINGS = 3;
50 | static final int COMMAND_ACTIVITY = 5;
51 | static final int TABLE_ROW_MARGIN = 6;
52 |
53 | private Handler handler = null;
54 | private Intent serviceIntent = null;
55 | private ObdReaderServiceConnection serviceConn = null;
56 | private UpdateThread updater = null;
57 | private SensorManager sensorManager = null;
58 | private Sensor orientSensor = null;
59 | private double fuelEconAvg = 0;
60 | private int fuelEconi = 0;
61 | private double speedAvg = 0;
62 | private int speedi = 0;
63 | private SharedPreferences prefs = null;
64 | private double maxFuelEcon = 70.0;
65 | private PowerManager powerManager = null;
66 | private PowerManager.WakeLock wakeLock = null;
67 | private final SensorEventListener orientListener = new SensorEventListener() {
68 | public void onSensorChanged(SensorEvent event) {
69 | float x = event.values[0];
70 | String dir = "";
71 | if (x >= 337.5 || x < 22.5) {
72 | dir = "N";
73 | } else if (x >= 22.5 && x < 67.5) {
74 | dir = "NE";
75 | } else if (x >= 67.5 && x < 112.5) {
76 | dir = "E";
77 | } else if (x >= 112.5 && x < 157.5) {
78 | dir = "SE";
79 | } else if (x >= 157.5 && x < 202.5) {
80 | dir = "S";
81 | } else if (x >= 202.5 && x < 247.5) {
82 | dir = "SW";
83 | } else if (x >= 247.5 && x < 292.5) {
84 | dir = "W";
85 | } else if (x >= 292.5 && x < 337.5) {
86 | dir = "NW";
87 | }
88 | TextView compass = (TextView)findViewById(R.id.compass_text);
89 | updateTextView(compass,dir);
90 | }
91 |
92 | public void onAccuracyChanged(Sensor sensor, int accuracy) {
93 | // TODO Auto-generated method stub
94 | }
95 | };
96 |
97 | /** Called when the activity is first created. */
98 | @Override
99 | public void onCreate(Bundle savedInstanceState) {
100 | super.onCreate(savedInstanceState);
101 | // ExceptionHandler.register(this,"http://www.whidbeycleaning.com/droid/server.php");
102 | setContentView(R.layout.main);
103 | handler = new Handler();
104 | serviceIntent = new Intent(this, ObdReaderService.class);
105 | serviceConn = new ObdReaderServiceConnection();
106 | bindService(serviceIntent, serviceConn, Context.BIND_AUTO_CREATE);
107 | LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
108 | if (locationManager == null) {
109 | showDialog(NO_GPS_ID);
110 | return;
111 | }
112 | final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
113 | if (mBluetoothAdapter == null) {
114 | showDialog(NO_BLUETOOTH_ID);
115 | return;
116 | }
117 | sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
118 | List sens = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
119 | if ( sens.size() <= 0) {
120 | Toast.makeText(this, "No orientation available.", Toast.LENGTH_LONG).show();
121 | } else {
122 | orientSensor = sens.get(0);
123 | }
124 | }
125 | @Override
126 | protected void onDestroy() {
127 | super.onDestroy();
128 | if (wakeLock.isHeld()) {
129 | wakeLock.release();
130 | }
131 | }
132 | @Override
133 | protected void onPause() {
134 | super.onPause();
135 | if (wakeLock.isHeld()) {
136 | wakeLock.release();
137 | }
138 | }
139 | protected void onResume() {
140 | super.onResume();
141 | sensorManager.registerListener(orientListener, orientSensor, SensorManager.SENSOR_DELAY_UI);
142 | prefs = PreferenceManager.getDefaultSharedPreferences(this);
143 | maxFuelEcon = ObdReaderConfigActivity.getMaxFuelEconomy(prefs);
144 | powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
145 | wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "ObdReader");
146 | }
147 | private void updateConfig() {
148 | Intent configIntent = new Intent(this,ObdReaderConfigActivity.class);
149 | startActivity(configIntent);
150 | }
151 | public boolean onCreateOptionsMenu(Menu menu) {
152 | menu.add(0, START_LIVE_DATA, 0, "Start Live Data");
153 | menu.add(0, SETTINGS, 0, "Settings");
154 | menu.add(0, COMMAND_ACTIVITY, 0, "Run Command");
155 | menu.add(0, STOP_LIVE_DATA, 0, "Stop");
156 | return true;
157 | }
158 | public boolean onOptionsItemSelected(MenuItem item) {
159 | switch (item.getItemId()) {
160 | case START_LIVE_DATA:
161 | liveData();
162 | return true;
163 | case STOP_LIVE_DATA:
164 | cancel();
165 | return true;
166 | case SETTINGS:
167 | updateConfig();
168 | return true;
169 | case COMMAND_ACTIVITY:
170 | staticCommand();
171 | return true;
172 | }
173 | return false;
174 | }
175 | private void staticCommand() {
176 | Intent commandIntent = new Intent(this, ObdReaderCommandActivity.class);
177 | startActivity(commandIntent);
178 | }
179 | private void liveData() {
180 | if (!serviceConn.isRunning()) {
181 | serviceConn.getService().startService();
182 | }
183 | updater = new UpdateThread();
184 | updater.start();
185 | wakeLock.acquire();
186 | }
187 | private void cancel() {
188 | stopService(serviceIntent);
189 | if (serviceConn.isRunning()) {
190 | serviceConn.getService().stopService();
191 | }
192 | if (updater != null) {
193 | updater.stop = true;
194 | }
195 | wakeLock.release();
196 | }
197 | protected Dialog onCreateDialog(int id) {
198 | AlertDialog.Builder build = new AlertDialog.Builder(this);
199 | switch(id) {
200 | case NO_BLUETOOTH_ID:
201 | build.setMessage("Sorry, your device doesn't support bluetooth");
202 | return build.create();
203 | case NO_GPS_ID:
204 | build.setMessage("Sorry, your device doesn't support gps");
205 | return build.create();
206 | }
207 | return null;
208 | }
209 | public boolean onPrepareOptionsMenu(Menu menu) {
210 | MenuItem startItem = menu.findItem(START_LIVE_DATA);
211 | MenuItem stopItem = menu.findItem(STOP_LIVE_DATA);
212 | MenuItem settingsItem = menu.findItem(SETTINGS);
213 | MenuItem commandItem = menu.findItem(COMMAND_ACTIVITY);
214 | if (serviceConn.isRunning()) {
215 | startItem.setEnabled(false);
216 | stopItem.setEnabled(true);
217 | settingsItem.setEnabled(false);
218 | commandItem.setEnabled(false);
219 | } else {
220 | stopItem.setEnabled(false);
221 | startItem.setEnabled(true);
222 | settingsItem.setEnabled(true);
223 | commandItem.setEnabled(true);
224 | }
225 | return true;
226 | }
227 | public void updateDataTable(final Map dataMap) {
228 | handler.post(new Runnable() {
229 | public void run() {
230 | setDataTableText(dataMap);
231 | }
232 | });
233 | }
234 | public void updateTextView(final TextView view, final String txt) {
235 | handler.post(new Runnable() {
236 | public void run() {
237 | view.setText(txt);
238 | }
239 | });
240 | }
241 | public void setDataTableText(Map dataMap) {
242 | TableLayout tl = (TableLayout) findViewById(R.id.data_table);
243 | tl.removeAllViews();
244 | Set keySet = dataMap.keySet();
245 | String[] keys = keySet.toArray(new String[0]);
246 | Arrays.sort(keys);
247 | for (String k:keys) {
248 | addTableRow(tl,k,dataMap.get(k));
249 | }
250 | String coolant = dataMap.get(ObdConfig.COOLANT_TEMP);
251 | String runTime = dataMap.get(ObdConfig.RUN_TIME);
252 | String rpm = dataMap.get(ObdConfig.RPM);
253 | String fuelEcon = dataMap.get(ObdConfig.FUEL_ECON);
254 | String fuelEconMap = dataMap.get(ObdConfig.FUEL_ECON_MAP);
255 | String speed = dataMap.get(ObdConfig.SPEED);
256 | String temp = dataMap.get(ObdConfig.INTAKE_TEMP);
257 | if (coolant != null) {
258 | setCoolantTemp(coolant);
259 | }
260 | if (isFill(fuelEcon)) {
261 | if (!isFill(fuelEconMap)) {
262 | setFuelEconomy(fuelEconMap);
263 | }
264 | } else {
265 | setFuelEconomy(fuelEcon);
266 | }
267 | setRunTime(runTime);
268 | setRpm(rpm);
269 | setAvgSpeed(speed);
270 | setAirTemp(temp);
271 | }
272 | private void setAirTemp(String temp) {
273 | if (isFill(temp)) {
274 | return;
275 | }
276 | TextView tempView = (TextView)findViewById(R.id.air_temp_text);
277 | tempView.setText(temp);
278 | }
279 | private void setAvgSpeed(String spd) {
280 | try {
281 | String[] spds = spd.split(" ");
282 | int spdv = Integer.parseInt(spds[0]);
283 | if ("km/h".equals(spds[1])) {
284 | spdv = (int)((double)spdv / .625);
285 | }
286 | if (spdv > 0) {
287 | speedAvg = (spdv + (speedi*speedAvg)) / (speedi + 1);
288 | speedi += 1;
289 | }
290 | TextView avgSpeed = (TextView)findViewById(R.id.avg_spd_text);
291 | spdv = (int)speedAvg;
292 | if ("km/h".equals(spds[1])) {
293 | spdv = (int)(speedAvg*.625);
294 | }
295 | avgSpeed.setText(String.format("%d %s", spdv, spds[1]));
296 | } catch (Exception e) {
297 | }
298 | }
299 | private boolean isFill(String data) {
300 | if ("--".equals(data) || "NODATA".equals(data)) {
301 | return true;
302 | }
303 | return false;
304 | }
305 | private void setRpm(String rpm) {
306 | if (isFill(rpm)) {
307 | return;
308 | }
309 | TextView rpmView = (TextView)findViewById(R.id.avg_rpm_text);
310 | rpmView.setText(rpm);
311 | }
312 | private void setRunTime(String runTime) {
313 | if (isFill(runTime)) {
314 | return;
315 | }
316 | TextView runTimeView = (TextView)findViewById(R.id.run_time_text);
317 | runTimeView.setText(runTime);
318 | }
319 | private void setFuelEconomy(String fuelEcon) {
320 | try {
321 | String[] econs = fuelEcon.split(" ");
322 | double econ = Double.parseDouble(econs[0]);
323 | if ("kml".equals(econs[1])) {
324 | econ = econ / 0.354013;
325 | }
326 | if (econ > 0 && econ <= maxFuelEcon) {
327 | fuelEconAvg = (econ + (fuelEconi*fuelEconAvg)) / (fuelEconi + 1);
328 | fuelEconi += 1;
329 | }
330 | TextView instEcon = (TextView)findViewById(R.id.inst_fuel_econ_text);
331 | TextView avgEcon = (TextView)findViewById(R.id.avg_fuel_econ_text);
332 | TextView avgEconlbl = (TextView)findViewById(R.id.avg_fuel_econ_lbl);
333 | instEcon.setText(fuelEcon);
334 | String lbl = "mpg";
335 | if ("kml".equals(econs[1])) {
336 | econ = fuelEconAvg * 0.354013;
337 | lbl = "kml";
338 | }
339 | avgEcon.setText(String.format("%d", Math.round(fuelEconAvg)));
340 | avgEconlbl.setText(lbl);
341 | } catch (Exception e) {
342 | // TODO: handle exception
343 | }
344 | }
345 | private void setCoolantTemp(String coolant) {
346 | try {
347 | String[] cools = coolant.split(" ");
348 | int temp = Integer.parseInt(cools[0]);
349 | if ("F".equals(cools[1])) {
350 | temp = (temp - 32) * 5 / 9;
351 | }
352 | CoolantGaugeView gauge = (CoolantGaugeView)findViewById(R.id.coolant_gauge);
353 | gauge.setTemp(temp);
354 | } catch (Exception e) {
355 | }
356 | }
357 | private void addTableRow(TableLayout tl, String key, String val) {
358 | TableRow tr = new TableRow(this);
359 | MarginLayoutParams params = new ViewGroup.MarginLayoutParams(
360 | LayoutParams.WRAP_CONTENT,
361 | LayoutParams.WRAP_CONTENT);
362 | params.setMargins(TABLE_ROW_MARGIN,TABLE_ROW_MARGIN,TABLE_ROW_MARGIN,TABLE_ROW_MARGIN);
363 | tr.setLayoutParams(params);
364 | tr.setBackgroundColor(Color.BLACK);
365 | TextView name = new TextView(this);
366 | name.setGravity(Gravity.RIGHT);
367 | name.setText(key + ": ");
368 | TextView value = new TextView(this);
369 | value.setGravity(Gravity.LEFT);
370 | value.setText(val);
371 | tr.addView(name);
372 | tr.addView(value);
373 | tl.addView(tr,new TableLayout.LayoutParams(
374 | LayoutParams.WRAP_CONTENT,
375 | LayoutParams.WRAP_CONTENT));
376 | }
377 | private class UpdateThread extends Thread {
378 | boolean stop = false;
379 | public void run() {
380 | String vehicleId = prefs.getString(ObdReaderConfigActivity.VEHICLE_ID_KEY,"");
381 | while (!stop && serviceConn.isRunning()) {
382 | ObdReaderService svc = serviceConn.getService();
383 | Map dataMap = null;
384 | if (svc == null || svc.getDataMap() == null) {
385 | dataMap = new HashMap();
386 | for (ObdCommand cmd:ObdConfig.getCommands()) {
387 | dataMap.put(cmd.getDesc(),"--");
388 | }
389 | } else {
390 | dataMap = svc.getDataMap();
391 | }
392 | if (vehicleId != null && !"".equals(vehicleId.trim())) {
393 | dataMap.put("Vehicle ID", vehicleId);
394 | }
395 | updateDataTable(dataMap);
396 | try {
397 | Thread.sleep(ObdReaderConfigActivity.getUpdatePeriod(prefs));
398 | } catch (InterruptedException e) {
399 | e.printStackTrace();
400 | }
401 | }
402 | }
403 | }
404 | }
405 |
--------------------------------------------------------------------------------