Android蓝牙连接到ELM327 / OBD2设备

时间:2019-08-15 03:27:48

标签: android bluetooth obd-ii

我试图创建一个简单的android应用程序以连接到我的ELM327设备以获取一些汽车诊断数据。但是我无法通过我的android手机和我的ELM327设备建立蓝牙连接。

我的代码非常简单,如下所示:

公共类蓝牙{     受保护的BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();     私人ConnectThread mConnectThread = null;     私有AcceptThread mAcceptThread = null;     私有WorkerThread mWorkerThread = null;     专用BluetoothDevice mOBDDevice = null;     专用BluetoothSocket mSocket = null;     私有字符串uuid;

  try {
            String string = " 2019-08-06 08:26:17";
            DateFormat format = new SimpleDateFormat("MMM dd,yyyy  hh:mm a");
            Date date = format.parse(string);
            Log.d("datesssss", date.toString());
        } catch (ParseException e) {
            Log.d("datessssError", e.toString());
        }

}

在mainactivity中,我将首先新建一个蓝牙类,然后调用bluetooth.connect():

mBluetooth =新的Bluetooth();  mBluetooth.connect();

调试程序时,通过查询名称为“ OBD”的所有绑定设备,可以得到ELM327蓝牙设备。我还能够获取设备的uuid并使用createRfcommSocketToServiceRecord创建套接字。但是在connect函数中,mSocket.connect()总是失败,返回值为-1并获得IOexception。

我的问题是:

  1. 当我的android应用程序连接到ELM327设备时,我的android手机是蓝牙客户端,而我的ELM327设备是蓝牙服务器,这种理解正确吗?
  2. ELM327设备上是否正在运行服务器程序以侦听并接受传入的连接?这是ELM327协议的已定义行为吗?
  3. 有人知道为什么mSocket.connect()失败了吗?对如何研究这个问题有任何想法吗?还是程序中有任何明显的错误?谢谢。

2 个答案:

答案 0 :(得分:1)

问题解决了。参见下面的源代码:

public synchronized void connect() throws IOException {
        try {
            // Get a BluetoothSocket to connect with the given BluetoothDevice.
            // MY_UUID is the app's UUID string, also used in the server code.
            mSocket = mOBDDevice.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
        } catch (IOException e) {
            Log.e(TAG, "Socket's create() method failed", e);
        }

        try {
            // Connect to the remote device through the socket. This call blocks
            // until it succeeds or throws an exception.
            mSocket.connect();
        } catch (IOException e1) {
            Log.e(TAG, "There was an error while establishing Bluetooth connection. Falling back..", e1);
            Class<?> clazz = mSocket.getRemoteDevice().getClass();
            Class<?>[] paramTypes = new Class<?>[]{Integer.TYPE};
            try {
                Method m = clazz.getMethod("createRfcommSocket", paramTypes);
                Object[] params = new Object[]{Integer.valueOf(1)};
                mFallbackSocket = (BluetoothSocket) m.invoke(mSocket.getRemoteDevice(), params);
                mFallbackSocket.connect();
                mSocket.close();
                mSocket = mFallbackSocket;
            } catch (Exception e2) {
                Log.e(TAG, "Couldn't fallback while establishing Bluetooth connection.", e2);
                mSocket.close();
                //throw new IOException();
            }
        }
        inputStream = mSocket.getInputStream();
        outputStream = mSocket.getOutputStream();
    }

答案 1 :(得分:0)

我对Android不太了解,尽管我对OBD2及其它知识也很了解。

  1. 这取决于适配器的类型。如果您有WiFi适配器,则可以认为该适配器是服务器,而您是客户端。您连接到一个套接字,然后从中读取。对于蓝牙适配器,情况有所不同。如果通过rfcomm连接,则它是串行协议,服务器和客户端都不是。如果您通过BTLE连接,那么OBD2加密狗就是外围设备,而您就是中央设备。

  2. 在WiFi适配器上,可以。但是,此行为不是ELM327的一部分。 ELM327仅指定串行命令。传输这些内容不是规范的一部分,因为它发生在上一层(WiFi,rfcomm,BTLE,USB等)。

  3. 您确定rfcomm通过套接字接口工作吗?这是一个串行接口,因此我希望有类似文件的操作。