关于怎么打开串口,请参考 点击打开链接
1,开线程监听串口数据
package com.android.server;
import android.util.Log;
import java.io.File;
public class ProcessCanBusThread extends Thread{
private static final String TAG = "ProcessCanBusThread";
private boolean flag = false;
ICanBusDataCallBack mICanBusDataCallBack; //数据上报应用层的interface
public ProcessCanBusThread(ICanBusDataCallBack mICanBusDataCallBack){
this.mICanBusDataCallBack = mICanBusDataCallBack;
this.start();
}
@Override
public void run() {
super.run();
while (!isInterrupted()) {
byte[] result = SystemParse.readCanBus();//数据过多,可以适当延时
if(result!=null){
if(null != mICanBusDataCallBack){
mICanBusDataCallBack.processReceiveBusData(result ,result.length);//数据上报
}
}
}
}
}
2,跟踪readCanBus方法
private static byte[] g_mcucom_bakdata = new byte[256];
private static int g_cancom_baklen;
private static byte[] g_cancom_bakdata = new byte[256];
public static boolean flag;
public static byte[] readCanBus(){
int size = 0;
byte[] buffer = new byte[1024];
if(mCanInputStream!=null){
try {
size = mCanInputStream.read(buffer);
if (size > 0) {
if(g_cancom_baklen>0){
size += g_cancom_baklen;
byte[] tempbuffer = new byte[size];
for(int i=0;i<g_cancom_baklen;i++){
tempbuffer[i] = g_cancom_bakdata[i];
}
for(int i=g_cancom_baklen;i<size;i++){
tempbuffer[i] = buffer[i-g_cancom_baklen];
}
g_cancom_baklen = 0;
return onCanDataReceived(tempbuffer, size);
}else{
return onCanDataReceived(buffer, size);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}else{
Log.e(TAG, "=====the canbus port is error====");
}
return null;
}
3,跟踪onCanDataReceived方法
// 2E 21 02 Data0 Data1 DataN CheckSum
//HeadCode DataType Length Data0 Data1 DataN CheckSum
//Length =Data0+ Data1+ DataN
//ChechSum =(DataType+ Length+ Data0+ Data1+ DataN)^0xFF
private static byte[] onCanDataReceived(final byte[] buffer ,final int size){
byte[] datacheck = new byte[4];
int starti;
for(int i=0;i<size;i++){
datacheck[0] = buffer[i];
starti = i;
if(datacheck[0]==(byte)0x2e){
i++;
if(i>=size){
for(int k=starti;k<size;k++){
g_cancom_bakdata[k-starti] = buffer[k];
g_cancom_baklen++;
}
return null;
}
if(i>=size-1){
for(int k=starti;k<size;k++){
g_cancom_bakdata[k-starti] = buffer[k];
g_cancom_baklen++;
}
return null;
}
datacheck[1] = buffer[i+1];//len
if(datacheck[1]>0){
if((starti+datacheck[1]+4)<=size){
//i++;
byte[] tempdata = new byte[datacheck[1]+2];
for(int j=0;j<(datacheck[1]+2);j++){
tempdata[j] = buffer[i++];
datacheck[2] += (byte) tempdata[j];
}
datacheck[2] ^= 0xFF;
if(datacheck[2]==buffer[i]){
g_cancom_baklen = 0;
response((int)0xff);//给canbus回0xff表示该帧数据正确
return tempdata;
}else{
}
}else{
for(int k=starti;k<size;k++){
g_cancom_bakdata[k-starti] = buffer[k];
g_cancom_baklen++;
}
}
}
}
}
return null;
}
public static void response(int hex){
if (mOutputStream != null){
try{
mCanOutputStream.write(hex);
} catch (IOException e) {
Log.e(TAG, "SendCanCommand IOException occurred: " + e);
}
}
}
到这里,基本上canbus发过来的每帧数据都能接收到,现在就是上报到应用层,通过ICanBusDataCallBack
Android系统中services中的数据怎么通过jni或者外部提供的接口(Manger class)上报的,这里就不过多解释了。
下面看应用层收到数据后的处理(譬如空调的显示,车门信息,车辆状态等)
请先下载该apk 点击打开链接(关于数据解析apk)
找到CanBusService.java类
package com.md.zcanbus.stack;
import android.app.Service;
import android.commcu.CanComDataPtr;
import android.commcu.McuSerialManager;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;
import com.md.CUtils;
import com.md.CanBusImpl;
import com.md.source.SystemFreq;
import com.md.source.SystemModel;
import com.md.source.SystemTime;
import com.md.source.SystemVox;
/**
* modify 20170503 for CanBus
* @author md
*/
public class CanBusService extends Service {
private static McuSerialManager gMCM = McuSerialManager.getInstance();
private static RemoteCallbackList<ICanBusService> callbacks;
private ICanBusService cb;
public static CanBusService reference = new CanBusService();
public CanBusService() {}
public static CanBusService getReference(){
synchronized (reference) {
if(reference==null){
reference = new CanBusService();
}
}
return reference;
}
public void registerCallback(ICanBusService canllImpl) {
callbacks = new RemoteCallbackList<ICanBusService>();
if(callbacks!=null) callbacks.register(canllImpl);
Log.d("md", "registerCallback :"+ callbacks);
}
public void unregisterCallback() {
if(callbacks!=null && cb!=null) callbacks.unregister(cb);
}
@Override
public void onDestroy() {
unregisterCallback();
super.onDestroy();
}
public void requestCanData(){
CUtils.init();
gMCM.sendCanBusMultiData(0x90, (byte)0x24);
gMCM.sendCanBusMultiData(0x90, (byte)0x41);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// CanBusService busService = CanBusService.getReference();
registerCallback(CanBusImpl.getInstance().getCallBack(getApplicationContext()));
onActionListener();
requestCanData();
return super.onStartCommand(intent, flags, startId);
}
public void onActionListener(){
if(null==gMCM){
gMCM = McuSerialManager.getInstance();
}
gMCM.setCanbusDataListener(onActionListener,1);
}
McuSerialManager.CanbusDataListener onActionListener = new McuSerialManager.CanbusDataListener() {
@Override
public int onAction(int arg0, byte[] arg1) {
Message message = new Message();
message.what = arg0;
message.obj = arg1;
handler.sendMessage(message);
return 0;
}
};
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
int ptr = msg.what;
byte[] result = (byte[]) msg.obj;
if(callbacks!=null) {
int i = callbacks.beginBroadcast();
while(i > 0){
i--;
cb = callbacks.getBroadcastItem(i);
}
}
try {
switch (ptr) {
case CanComDataPtr.CANBUS_PTR_0X00:
Config.bs00 = bytes(result, Config.bs00);
if(cb!=null) cb.notify_CANBUS_PTR_0X00();
break;
case CanComDataPtr.CANBUS_PTR_0X01:
Config.bs01 = bytes(result, Config.bs01);
if(cb!=null) cb.notify_CANBUS_PTR_0X01();
break;
case CanComDataPtr.CANBUS_PTR_0X02:
Config.bs02 = bytes(result, Config.bs02);
if(cb!=null) cb.notify_CANBUS_PTR_0X02();
break;
.
.代码过多省略
.
break;
default:
break;
}
} catch (RemoteException e) {
e.printStackTrace();
}
if(callbacks!=null) callbacks.finishBroadcast();
}
};
private void startDelay(){
Log.d("md", "==startDelay==");
Thread thread =new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
requestCanData();
}
});
try {
thread.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public byte[] bytes(byte[] bs,byte[] result){
result = new byte[bs.length-2];
for (int i = 2; i < bs.length; i++) {
result[i-2] = bs[i];
}
return result;
}
}
其中重要的是handler,handler中message包含canbus给过来的每一帧数据,ptr是该帧的data[0],自己在services那层处理好
McuSerialManager.CanbusDataListener的public int onAction(int ptr, byte[] others)
到此,数据就获取完全
详情如下
里面的详细方法说明就略过了。
资料下载点击打开链接
备注: 以上的串口通信可以直接写在apk中,不用在services层处理,也可以根据自己的实际情况,如果services层用到CanBus中的数据,最好写在services层,方便全局控制。
更详细的demo,后续有需要的话,再传上来。
希望能帮到各位。。。