驾驶培训APP流程图一(读取IC卡流程)

背景

全志平台Android4.4系统
公司原有的wince显示屏已经不能满足公司业务需求,使用android系统开发我司下一代产品。
由于android系统功能强大,可应用的范围不止步于显示屏一个产品。为考虑产品的可维护性,现重新设计一套系统框架,以满足开发项目的需求。

架构图

MMCU在这里插入图片描述

描述

考过驾照的都知道一套流程,科目二科目三是需要上传学时的,到省平台审核到学时到一定时长才能预约考试

主要制定了和终端MCU模块的通信,以及按照省平台的要求和平台进行tcp的通信。
本篇着重描述MUC通信过程

代码走向

myApp-----------
动态注册一个广播MyReceiver ,同时另一个App发送MCU请求

IntentFilter updateIntent = new IntentFilter();
		updateIntent.addAction(ACTION_00_01);// mcu信息查询
		updateIntent.addAction(ACTION_10_00);// 实时信息
		updateIntent.addAction(ACTION_10_17);// 读取身份证
		updateIntent.addAction(ACTION_20_02);// 读IC卡
		mCardBroadcast = new Hst55Receiver();
		registerReceiver(mCardBroadcast, updateIntent);
/* 打包发送 */
	public void handOutCommand(Context context) {
		Intent intent = new Intent();
		intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
		intent.setAction(Constant.MCU_SEND_ACTION);
		/*Log.i("MCUCMD","test_data");
		Log.i("MCUCMD",StringUtils.byteToString(readHead())+"\n"+GetCmdLen());
		for(byte b:readHead()){
			Log.i("MCUCMD",b+"");
		}*/
		intent.putExtra("size", GetCmdLen());
		intent.putExtra("data", readHead());
		intent.putExtra("reSend", reSend);
		context.sendBroadcast(intent, null);
	}

在一个app启动时,也启动了另外一个app的service

APPlication
if (isHst55Running == false) {
				CatchApplication.showLog("主界面启动hst55");
				HelpFuns.StartExternalService(context, "com.hst.cz.hst55", "com.hst.cz.hst55.ServiceRun");
			}
 <service
            android:name="com.hst.cz.hst55.ServiceRun"
            android:exported="true" >//这属性表明了支持另外的应用启动这个服务
        </service>

恰好这个service里面是动态的注册了广播MCU请求广播

	try {
			getSerialPort();// 获取端口
			mOutputStream = mSerialPort.getOutputStream();// 获取输出流
			mInputStream = mSerialPort.getInputStream();// 获取输入流
			/* Create a receiving thread */
			mReadThread = new ReadThread();// 创建线程
			mReadThread.start();// 开始运行
		} catch (SecurityException e) {
		} catch (IOException e) {
		} catch (InvalidParameterException e) {
		}
		if (mSerialPort != null) {
			IntentFilter filter = new IntentFilter();
			filter.addAction(Constant.MCU_SEND_ACTION); // 添加动态广播的Action
			sendReceiver.setOutputStream(mOutputStream, getApplicationContext());
			registerReceiver(sendReceiver, filter);//然后,receiver接受到了MCU请求,开始和MCU模块通信

		}

里面的OutputStream是程序对mcu的写入流

SerialPort
{
private FileOutputStream mFileOutputStream;

	public SerialPort(File device, int baudrate, int flags) 
	{
		/* Check access permission */
		if (!device.canRead() || !device.canWrite()) 
		{
			try 
			{
				/* Missing read/write permission, trying to chmod the file */
				Process su;
				su = Runtime.getRuntime().exec("/system/bin/su");
				String cmd = "chmod 666 " + device.getAbsolutePath() + "\n"
						+ "exit\n";
				su.getOutputStream().write(cmd.getBytes());
				
				if ((su.waitFor() != 0) || !device.canRead() || !device.canWrite()) 
				{
					throw new SecurityException();
				}
			}
			catch (Exception e) 
			{
				e.printStackTrace();
				throw new SecurityException();
			}
		}
		mFd = open(device.getAbsolutePath(), baudrate, flags);//这个open方法是通过jni访问底层MCU
		if (mFd == null) 
		{
			Log.e(TAG, "native open returns null");
//			throw new IOException();
		}
		mFileInputStream = new FileInputStream(mFd);
		mFileOutputStream = new FileOutputStream(mFd);
	}
}

service也会开启线程来轮询MCU发回来的信息

private class ReadThread extends Thread {
		@Override
		public void run() {
			super.run();
			byte[] buffer = new byte[2048];
			int size = 0;
			byte[] bufferTemp = new byte[2048];
			int sizeTemp = 0;
			while (!isInterrupted())// 串口如果有数据
			{
				try {
					if (mInputStream == null)
						return;
					sizeTemp = mInputStream.read(bufferTemp, 0, 2000);// 读取
					if (sizeTemp > 0) {
						if (size + sizeTemp <= buffer.length) {
							System.arraycopy(bufferTemp, 0, buffer, size, sizeTemp);
							size += sizeTemp;
							onDataReceived(buffer, size);// 转发
							size = 0;
						} else {
							size = 0;
						}
					}
				} catch (IOException e) {
					e.printStackTrace();
					return;
				}
			}
		}
	}

也会开启线程来给最初调用最初的app注册的接收者

	new Thread() {
			public void run() {
				while (true) {
					while (comCmdArray.size() > 0) {
						McuCmd tmp = comCmdArray.get(0);
						if (tmp != null) {
							handOutCommand(tmp);//发送广播
						}
						comCmdArray.remove(0);
					}
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}.start();

请求App的MyReceiver的定义如下

public class Hst55Receiver extends BroadcastReceiver {
	private static HandleCmdMcu handleCmdMcu = new HandleCmdMcu();

	@Override
	public void onReceive(Context context, Intent intent) {
		handleCmdMcu.putIntent(intent, context);
	}
}
public void putIntent(Intent intent, Context context) {
		int size = intent.getIntExtra("size", 0);
		if (size > 0) {
			setContext(context);
			McuCmd cmd = new McuCmd();
			byte hp[] = intent.getByteArrayExtra("data");
			cmd.initStmCmd(hp, size);
			McuHandleCmd(cmd);//从这里即开始了接口回调
		}
	}

接口回调


	/*
	 * 电源设备管理
	 */
	private void getCardInfo(McuCmd cmd) {
		GetCardInfo.getCardInfo(context, cmd);
		if (mGetCardInfoLintener != null) {
			mGetCardInfoLintener.getCardInfo();
		}
	}

	@Override
	public void McuHandleCmd(McuCmd cmd) {
		switch (cmd.GetSubOrder()) {
		case 0x02: {
			getCardInfo(cmd);
		}
			break;
		}
	}

UI界面在回调,显示卡片信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值