gpt4 book ai didi

android - 如何通过 Android 蓝牙连接到 OBDII

转载 作者:行者123 更新时间:2023-12-05 00:06:55 25 4
gpt4 key购买 nike

目前我一直在使用这个引用 http://blog.lemberg.co.uk/how-guide-obdii-reader-app-development但我仍然对我的 Android 应用程序能够连接到 OBDII 的下一步是什么感到困惑。我在网上找到了一个简单的蓝牙应用程序的代码。该应用程序能够与其他 Android 手机建立蓝牙连接,但不能与 OBDII 建立蓝牙连接。

public class MainActivity extends Activity {

Button b1,b2,b3,b4;
private BluetoothAdapter BA;
private Set<BluetoothDevice>pairedDevices;
ListView lv;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

b1 = (Button) findViewById(R.id.button);
b2=(Button)findViewById(R.id.button2);
b3=(Button)findViewById(R.id.button3);
b4=(Button)findViewById(R.id.button4);

BA = BluetoothAdapter.getDefaultAdapter();
lv = (ListView)findViewById(R.id.listView);
}

public void on(View v) {
if (!BA.isEnabled()) {
Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnOn, 0);
Toast.makeText(getApplicationContext(), "Turned on", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Already on", Toast.LENGTH_LONG).show();
}
}

public void off(View v) {
BA.disable();
Toast.makeText(getApplicationContext(), "Turned off", Toast.LENGTH_LONG).show();
}

public void visible(View v) {
Intent getVisible = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(getVisible, 0);
}

public void list(View v) {
pairedDevices = BA.getBondedDevices();

ArrayList list = new ArrayList();

for (BluetoothDevice bt : pairedDevices) list.add(bt.getName());
Toast.makeText(getApplicationContext(), "Showing Paired Devices", Toast.LENGTH_SHORT).show();

final ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, list);

lv.setAdapter(adapter);
}

展望 future ,必须做些什么才能使应用程序能够成功建立并保持与 OBDII 的蓝牙连接。

最佳答案

查看android-obd-reader OBDII 示例,可帮助您将 OBDII 与您的设备连接。

它正在使用 OBD-II Java API连接并从obd读取数据。

使用以下类,您可以管理连接并从 obd 读取数据。

BluetoothManager.java :它可以帮助您连接设备

public class BluetoothManager {

private static final String TAG = BluetoothManager.class.getName();
/*
* http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html
* #createRfcommSocketToServiceRecord(java.util.UUID)
*
* "Hint: If you are connecting to a Bluetooth serial board then try using the
* well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB. However if you
* are connecting to an Android peer then please generate your own unique
* UUID."
*/
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

/**
* Instantiates a BluetoothSocket for the remote device and connects it.
* <p/>
* See http://stackoverflow.com/questions/18657427/ioexception-read-failed-socket-might-closed-bluetooth-on-android-4-3/18786701#18786701
*
* @param dev The remote device to connect to
* @return The BluetoothSocket
* @throws IOException
*/
public static BluetoothSocket connect(BluetoothDevice dev) throws IOException {
BluetoothSocket sock = null;
BluetoothSocket sockFallback = null;

Log.d(TAG, "Starting Bluetooth connection..");
try {
sock = dev.createRfcommSocketToServiceRecord(MY_UUID);
sock.connect();
} catch (Exception e1) {
Log.e(TAG, "There was an error while establishing Bluetooth connection. Falling back..", e1);
Class<?> clazz = sock.getRemoteDevice().getClass();
Class<?>[] paramTypes = new Class<?>[]{Integer.TYPE};
try {
Method m = clazz.getMethod("createRfcommSocket", paramTypes);
Object[] params = new Object[]{Integer.valueOf(1)};
sockFallback = (BluetoothSocket) m.invoke(sock.getRemoteDevice(), params);
sockFallback.connect();
sock = sockFallback;
} catch (Exception e2) {
Log.e(TAG, "Couldn't fallback while establishing Bluetooth connection.", e2);
throw new IOException(e2.getMessage());
}
}
return sock;
}
}

ObdGatewayService.java :它有连接代码和从obd读取数据。
 import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import com.github.pires.obd.commands.protocol.EchoOffCommand;
import com.github.pires.obd.commands.protocol.LineFeedOffCommand;
import com.github.pires.obd.commands.protocol.ObdResetCommand;
import com.github.pires.obd.commands.protocol.SelectProtocolCommand;
import com.github.pires.obd.commands.protocol.TimeoutCommand;
import com.github.pires.obd.commands.temperature.AmbientAirTemperatureCommand;
import com.github.pires.obd.enums.ObdProtocols;
import com.github.pires.obd.exceptions.UnsupportedCommandException;
import com.github.pires.obd.reader.R;
import com.github.pires.obd.reader.activity.ConfigActivity;
import com.github.pires.obd.reader.activity.MainActivity;
import com.github.pires.obd.reader.io.ObdCommandJob.ObdCommandJobState;
import com.google.inject.Inject;

import java.io.File;
import java.io.IOException;

/**
* This service is primarily responsible for establishing and maintaining a
* permanent connection between the device where the application runs and a more
* OBD Bluetooth interface.
* <p/>
* Secondarily, it will serve as a repository of ObdCommandJobs and at the same
* time the application state-machine.
*/
public class ObdGatewayService extends AbstractGatewayService {

private static final String TAG = ObdGatewayService.class.getName();
@Inject
SharedPreferences prefs;

private BluetoothDevice dev = null;
private BluetoothSocket sock = null;

public void startService() throws IOException {
Log.d(TAG, "Starting service..");

// get the remote Bluetooth device
final String remoteDevice = prefs.getString(ConfigActivity.BLUETOOTH_LIST_KEY, null);
if (remoteDevice == null || "".equals(remoteDevice)) {
Toast.makeText(ctx, getString(R.string.text_bluetooth_nodevice), Toast.LENGTH_LONG).show();

// log error
Log.e(TAG, "No Bluetooth device has been selected.");

// TODO kill this service gracefully
stopService();
throw new IOException();
} else {

final BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
dev = btAdapter.getRemoteDevice(remoteDevice);


/*
* Establish Bluetooth connection
*
* Because discovery is a heavyweight procedure for the Bluetooth adapter,
* this method should always be called before attempting to connect to a
* remote device with connect(). Discovery is not managed by the Activity,
* but is run as a system service, so an application should always call
* cancel discovery even if it did not directly request a discovery, just to
* be sure. If Bluetooth state is not STATE_ON, this API will return false.
*
* see
* http://developer.android.com/reference/android/bluetooth/BluetoothAdapter
* .html#cancelDiscovery()
*/
Log.d(TAG, "Stopping Bluetooth discovery.");
btAdapter.cancelDiscovery();

showNotification(getString(R.string.notification_action), getString(R.string.service_starting), R.drawable.ic_btcar, true, true, false);

try {
startObdConnection();
} catch (Exception e) {
Log.e(
TAG,
"There was an error while establishing connection. -> "
+ e.getMessage()
);

// in case of failure, stop this service.
stopService();
throw new IOException();
}
showNotification(getString(R.string.notification_action), getString(R.string.service_started), R.drawable.ic_btcar, true, true, false);
}
}

/**
* Start and configure the connection to the OBD interface.
* <p/>
* See http://stackoverflow.com/questions/18657427/ioexception-read-failed-socket-might-closed-bluetooth-on-android-4-3/18786701#18786701
*
* @throws IOException
*/
private void startObdConnection() throws IOException {
Log.d(TAG, "Starting OBD connection..");
isRunning = true;
try {
sock = BluetoothManager.connect(dev);
} catch (Exception e2) {
Log.e(TAG, "There was an error while establishing Bluetooth connection. Stopping app..", e2);
stopService();
throw new IOException();
}

// Let's configure the connection.
Log.d(TAG, "Queueing jobs for connection configuration..");
queueJob(new ObdCommandJob(new ObdResetCommand()));

//Below is to give the adapter enough time to reset before sending the commands, otherwise the first startup commands could be ignored.
try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }

queueJob(new ObdCommandJob(new EchoOffCommand()));

/*
* Will send second-time based on tests.
*
* TODO this can be done w/o having to queue jobs by just issuing
* command.run(), command.getResult() and validate the result.
*/
queueJob(new ObdCommandJob(new EchoOffCommand()));
queueJob(new ObdCommandJob(new LineFeedOffCommand()));
queueJob(new ObdCommandJob(new TimeoutCommand(62)));

// Get protocol from preferences
final String protocol = prefs.getString(ConfigActivity.PROTOCOLS_LIST_KEY, "AUTO");
queueJob(new ObdCommandJob(new SelectProtocolCommand(ObdProtocols.valueOf(protocol))));

// Job for returning dummy data
queueJob(new ObdCommandJob(new AmbientAirTemperatureCommand()));

queueCounter = 0L;
Log.d(TAG, "Initialization jobs queued.");


}

/**
* This method will add a job to the queue while setting its ID to the
* internal queue counter.
*
* @param job the job to queue.
*/
@Override
public void queueJob(ObdCommandJob job) {
// This is a good place to enforce the imperial units option
job.getCommand().useImperialUnits(prefs.getBoolean(ConfigActivity.IMPERIAL_UNITS_KEY, false));

// Now we can pass it along
super.queueJob(job);
}

/**
* Runs the queue until the service is stopped
*/
protected void executeQueue() throws InterruptedException {
Log.d(TAG, "Executing queue..");
while (!Thread.currentThread().isInterrupted()) {
ObdCommandJob job = null;
try {
job = jobsQueue.take();

// log job
Log.d(TAG, "Taking job[" + job.getId() + "] from queue..");

if (job.getState().equals(ObdCommandJobState.NEW)) {
Log.d(TAG, "Job state is NEW. Run it..");
job.setState(ObdCommandJobState.RUNNING);
if (sock.isConnected()) {
job.getCommand().run(sock.getInputStream(), sock.getOutputStream());
} else {
job.setState(ObdCommandJobState.EXECUTION_ERROR);
Log.e(TAG, "Can't run command on a closed socket.");
}
} else
// log not new job
Log.e(TAG,
"Job state was not new, so it shouldn't be in queue. BUG ALERT!");
} catch (InterruptedException i) {
Thread.currentThread().interrupt();
} catch (UnsupportedCommandException u) {
if (job != null) {
job.setState(ObdCommandJobState.NOT_SUPPORTED);
}
Log.d(TAG, "Command not supported. -> " + u.getMessage());
} catch (IOException io) {
if (job != null) {
if(io.getMessage().contains("Broken pipe"))
job.setState(ObdCommandJobState.BROKEN_PIPE);
else
job.setState(ObdCommandJobState.EXECUTION_ERROR);
}
Log.e(TAG, "IO error. -> " + io.getMessage());
} catch (Exception e) {
if (job != null) {
job.setState(ObdCommandJobState.EXECUTION_ERROR);
}
Log.e(TAG, "Failed to run command. -> " + e.getMessage());
}

if (job != null) {
final ObdCommandJob job2 = job;
((MainActivity) ctx).runOnUiThread(new Runnable() {
@Override
public void run() {
((MainActivity) ctx).stateUpdate(job2);
}
});
}
}
}

/**
* Stop OBD connection and queue processing.
*/
public void stopService() {
Log.d(TAG, "Stopping service..");

notificationManager.cancel(NOTIFICATION_ID);
jobsQueue.clear();
isRunning = false;

if (sock != null)
// close socket
try {
sock.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}

// kill service
stopSelf();
}

public boolean isRunning() {
return isRunning;
}

public static void saveLogcatToFile(Context context, String devemail) {
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
emailIntent.setType("text/plain");
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{devemail});
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "OBD2 Reader Debug Logs");

StringBuilder sb = new StringBuilder();
sb.append("\nManufacturer: ").append(Build.MANUFACTURER);
sb.append("\nModel: ").append(Build.MODEL);
sb.append("\nRelease: ").append(Build.VERSION.RELEASE);

emailIntent.putExtra(Intent.EXTRA_TEXT, sb.toString());

String fileName = "OBDReader_logcat_" + System.currentTimeMillis() + ".txt";
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + File.separator + "OBD2Logs");
if (dir.mkdirs()) {
File outputFile = new File(dir, fileName);
Uri uri = Uri.fromFile(outputFile);
emailIntent.putExtra(Intent.EXTRA_STREAM, uri);

Log.d("savingFile", "Going to save logcat to " + outputFile);
//emailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(Intent.createChooser(emailIntent, "Pick an Email provider").addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));

try {
@SuppressWarnings("unused")
Process process = Runtime.getRuntime().exec("logcat -f " + outputFile.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
}
}

}

我希望它对你有帮助。如果需要更多帮助,请留下评论或编辑您的问题。

关于android - 如何通过 Android 蓝牙连接到 OBDII,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41916727/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com