Java Android蓝牙OBDII通信
我不知道这是怎么回事。我正在尝试从蓝牙ELM327发送和接收数据。Torque工作正常,我使用了一个终端应用程序来发送命令,并返回正确的结果。所以我不明白我做错了什么。这是处理所有这些的线程。我正在使用Pires java obd库 对于所有的初始化命令,我都会返回一个“?”,但是当我开始循环vin命令时,它开始返回“OK”,并且在某一点上我能够正确地获得vin,但是我必须循环很多次才能得到它 返回套接字时正在建立连接。命令(按照库)以L0的格式发送Java Android蓝牙OBDII通信,java,android,multithreading,bluetooth,obd-ii,Java,Android,Multithreading,Bluetooth,Obd Ii,我不知道这是怎么回事。我正在尝试从蓝牙ELM327发送和接收数据。Torque工作正常,我使用了一个终端应用程序来发送命令,并返回正确的结果。所以我不明白我做错了什么。这是处理所有这些的线程。我正在使用Pires java obd库 对于所有的初始化命令,我都会返回一个“?”,但是当我开始循环vin命令时,它开始返回“OK”,并且在某一点上我能够正确地获得vin,但是我必须循环很多次才能得到它 返回套接字时正在建立连接。命令(按照库)以L0的格式发送 out.write((cmd+“\r”).g
out.write((cmd+“\r”).getBytes();
out.flush()代码>
我尝试将父发送和接收命令放在单独的阻塞线程中(使用Thread.join()
),但没有改变任何事情。我将延迟设置为Thread.sleep(1500)
,没有任何更改。我不知道还能尝试什么,而且我对android和蓝牙开发也相当陌生,所以非常感谢您提供的任何帮助
以下是从UI线程调用的线程的代码:
public class spawnThread implements Runnable {
protected BlockingQueue<obj> jobsQueue = new LinkedBlockingQueue<>();
protected Long queueCounter = 0L;
protected BluetoothSocket sock = null;
protected ArrayList<obj> process_list;
protected Handler main_handler;
protected setting_objs temp_objs = new setting_objs();
protected BluetoothDevice bt_device;
protected boolean initialized = false;
protected boolean can_continue = true;
public spawnThread(Handler handler, BluetoothDevice bt_device, ArrayList<obj> list) {
this.jobsQueue = new LinkedBlockingQueue<>();
this.queueCounter = 0L;
this.bt_device = bt_device;
this.process_list = list;
this.main_handler = handler;
}
public void run() {
while (!Thread.interrupted() && can_continue) {
if(sock == null){
bluetooth_init();
}
if(!initialized && can_continue){
init_commands();
}
if(can_continue){
testing_commands();
}
}
}
private void bluetooth_init(){
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
try {
sock = bt_device.createRfcommSocketToServiceRecord(uuid);
sock.connect();
} catch (IOException e) {
e.printStackTrace();
can_continue = false;
}
}
private void init_commands(){
ArrayList<obj> init_objs = temp_objs.init_array;
for (obj init_cmd:init_objs
) {
queueJob(init_cmd);
}
try {
executeQueue();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void testing_commands(){
String vin = "";
obj vin_obj = temp_objs.find_by_value("VIN");
for(int j = 0; j < 15; j++){
queueJob(vin_obj);
try {
executeQueue();
} catch (InterruptedException e) {
e.printStackTrace();
}
vin = vin_obj.command.getFormattedResult();
Log.d("vin count: " + String.valueOf(j)+ " ", vin);
}
}
private void queueJob(obj current) {
queueCounter++;
current.getCommand_job().setId(queueCounter);
try {
jobsQueue.put(current);
} catch (InterruptedException e) {
current.getCommand_job().setState(ObdCommandJob.ObdCommandJobState.QUEUE_ERROR);
Log.e("OBD LOG", "Failed to queue job.");
}
}
private void executeQueue() throws InterruptedException {
while (jobsQueue.size() > 0) {
ObdCommandJob job = null;
obj job_obj = null;
try {
job_obj = jobsQueue.take();
job = job_obj.getCommand_job();
job.setState(ObdCommandJob.ObdCommandJobState.RUNNING);
if (sock.isConnected()) {
job.getCommand().run(sock.getInputStream(), sock.getOutputStream());
//send data to be bundled.
if(job_obj != null){
bundle_data(job_obj);
}
} else {
job.setState(ObdCommandJob.ObdCommandJobState.EXECUTION_ERROR);
Log.e("OBD LOG", "Can't run command on a closed socket.");
}
} catch (InterruptedException i) {
Thread.currentThread().interrupt();
} catch (UnsupportedCommandException u) {
if (job != null) {
job.setState(ObdCommandJob.ObdCommandJobState.NOT_SUPPORTED);
Log.w("OBD LOG", "Command not supported. -> " + u.getMessage());
}
Log.w("OBD LOG", "Command not supported. -> " + u.getMessage());
Log.w("OBD LOG", "Job is null");
} catch (Exception e) {
if (job != null) {
job.setState(ObdCommandJob.ObdCommandJobState.EXECUTION_ERROR);
}
Log.e("OBD LOG", "Failed to run command. -> " + e.getMessage());
}
}
}
public类spawnThread实现可运行{
受保护的BlockingQueue作业队列=新建LinkedBlockingQueue();
受保护的长队列计数器=0L;
受保护的BluetoothSocket sock=null;
受保护的ArrayList进程列表;
受保护处理器主处理器;
受保护设置_objs temp_objs=新设置_objs();
受保护的蓝牙设备bt_设备;
受保护的布尔值初始化=false;
受保护布尔值can_continue=true;
公共线程(处理程序处理程序、BluetoothDevice bt_设备、ArrayList列表){
this.jobsQueue=新建LinkedBlockingQueue();
this.queueCounter=0L;
this.bt_设备=bt_设备;
this.process_list=list;
this.main_handler=handler;
}
公开募捐{
而(!Thread.interrupted()&&可以继续){
if(sock==null){
蓝牙初始化();
}
如果(!initialized&&可以继续){
init_命令();
}
如果(你能继续吗){
测试_命令();
}
}
}
私有无效蓝牙_init(){
UUID UUID=UUID.fromString(“000011101-0000-1000-8000-00805F9B34FB”);
试一试{
sock=bt_设备。createRfcommSocketToServiceRecord(uuid);
sock.connect();
}捕获(IOE异常){
e、 printStackTrace();
can_continue=false;
}
}
私有void init_命令(){
ArrayList init_objs=temp_objs.init_数组;
对于(obj init_cmd:init_objs
) {
queueJob(init_cmd);
}
试一试{
executeQueue();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
专用无效测试_命令(){
字符串vin=“”;
obj vin_obj=临时objs。通过值(“vin”)查找;
对于(int j=0;j<15;j++){
排队作业(vin_obj);
试一试{
executeQueue();
}捕捉(中断异常e){
e、 printStackTrace();
}
vin=vin_obj.command.getFormattedResult();
Log.d(“vin计数:”+String.valueOf(j)+“”,vin);
}
}
专用无效队列作业(obj当前){
队列计数器++;
current.getCommand_job().setId(queueCounter);
试一试{
jobsQueue.put(当前);
}捕捉(中断异常e){
current.getCommand_job().setState(ObdCommandJob.ObdCommandJobState.QUEUE_错误);
Log.e(“OBD日志”,“无法对作业排队”);
}
}
private void executeQueue()引发InterruptedException{
while(jobsQueue.size()>0){
ObdCommandJob作业=null;
obj job_obj=null;
试一试{
job_obj=jobsQueue.take();
job=job_obj.getCommand_job();
作业.setState(ObdCommandJob.ObdCommandJobState.RUNNING);
if(sock.isConnected()){
job.getCommand().run(sock.getInputStream(),sock.getOutputStream());
//发送要捆绑的数据。
如果(作业对象!=null){
捆绑数据(作业对象);
}
}否则{
作业.setState(ObdCommandJob.ObdCommandJobState.EXECUTION\u错误);
e(“OBD日志”,“无法在关闭的套接字上运行命令”);
}
}捕获(中断异常i){
Thread.currentThread().interrupt();
}捕获(不支持命令和异常u){
如果(作业!=null){
job.setState(不支持ObdCommandJob.ObdCommandJobState);
w(“OBD日志”,“不支持命令。->”+u.getMessage());
}
w(“OBD日志”,“不支持命令。->”+u.getMessage());
Log.w(“OBD日志”,“作业为空”);
}捕获(例外e){
如果(作业!=null){
作业.setState(ObdCommandJob.ObdCommandJobState.EXECUTION\u错误);
}
Log.e(“OBD日志”,“无法运行命令。->”+e.getMessage());
}
}
}
此链接提供了任何见解吗?不完全是。我只使用一个线程来处理与ELM327设备的通信。此线程(上面的代码)设置蓝牙套接字并运行命令。有对其他类的调用,但它在同一线程上。我尝试对从ELM327写入和读取的函数使用AsyncTasks,以确保它没有在同一时间发送/接收,但这没有解决/帮助任何问题。汽车点火开关打开了吗?您可能无法获取VIN a在模块重新进入睡眠状态后,如果点火开关关闭,或者甚至在点火开关打开一段时间后,它们都会进入睡眠状态。在测试过程中,汽车是打开的。如果我最终循环vin命令,我可以得到它,但它应该在第一次呼叫时出现…不是第10个ECU,你正在查询vin?此链接提供了任何信息吗?不是真的。我很抱歉