需求如下:
These are the filters, in priority order:
1- GetCardInput.AcqIndexList:
If application send this list, then the library must search just for these index in the table.
For example:
GetCardInput.AcqIndexList = ('1701', '1702', '1703').
In this case, if the card inserted/swiped does not match with these three rows, library must return GetCardOutput.ReturnCode = CARDAPPNAV.
IF GetCardInput.AcqIndexList == null, then try to filter by CardAppType:
2- GetCardInput.CardAppType:
If application sends GetCardInput.CardAppType == 1, then the library must filter all the table by app type and return just rows with app type == 1.
If application sends GetCardInput.CardAppType == 2, then the library must filter all the table by app type and return just rows with app type == 2.
If the card inserted/swiped does not match, library must return GetCardOutput.ReturnCode = CARDAPPNAV.
If application sends GetCardInput.CardAppType == 99, then the library use the hole table rows.
IF GetCardInput.CardAppType == 0, then try to filter by AcquirerId:
3- GetCardInput.AcquirerId:
In this case, the library must filter all the table by acquirer id;
4- If application sends GetCardInput.CardAppType != 0 and Acquirer Id != 0, then library must use the both values to filter the table.
1.在把AID添加到内核的时候执行添加动作。进入过滤状态设计模式。退出的时候就已经把值赋值好了。
首先,需要设置context类,这个类包括数据库句柄。
GetCardInput inputData;
List<AidInfo> filteredTable;用于保存从数据库里查询出来的AID及优先级。
public boolean addAidList() {cardFilterContext.setState(new InitialState(cardFilterContext));try {while (true) {cardFilterContext.applyFilter();if (cardFilterContext.getState() instanceof QuitFiltertable) {// Logic for quitting CVMLogs.d(TAG, "QuitFiltertable");addAidToEmvList();return true;}}} catch (Exception e) {e.printStackTrace();}return false;
其中,抽象状态类。要设置成抽象,因为还有公共的实现函数。并且把context类放在里面,
便于具体状态类继承并使用。
public abstract class State {protected CardFilterContext cardFilterContext;public State(CardFilterContext cardFilterContext ) {this.cardFilterContext = cardFilterContext;}static final String TAG = InitializeAppState.class.getSimpleName();public abstract void applyFilter();public List<AidInfo> processQueryResult(List<Map<String, Object>> queryResult) {List<AidInfo> aidInfoList = new ArrayList<>();for (Map<String, Object> result : queryResult) {// 根据实际情况处理每一行结果,并转换为 AidInfo 对象String aidValue = (String) result.get(EmvDbHelper.aid);int priority = (int) result.get(EmvDbHelper.aidPriority);
// byte priority = (byte) result.get(EmvDbHelper.aidPriority);Logs.d(TAG,"aidValue "+ aidValue);Logs.d(TAG,"aidPriority "+ priority);AidInfo aidInfo = new AidInfo(aidValue, (byte)priority);aidInfoList.add(aidInfo);}return aidInfoList;}
}
3.具体状态类。
public class InitialState extends State {private final String TAG = "InitialState";public InitialState(CardFilterContext context) {super(context);}@Overridepublic void applyFilter() {if (cardFilterContext.inputData.getAcqIndexList() != null && !cardFilterContext.inputData.getAcqIndexList().isEmpty()) {// Execute AcqIndexList filterList<String> acqIndexList = cardFilterContext.inputData.getAcqIndexList();List<Map<String, Object>> queryResult = queryDbWithAcqIndexList(acqIndexList,cardFilterContext.getDbManager());List<AidInfo> aidInfoList = processQueryResult(queryResult);cardFilterContext.setFilteredTable(aidInfoList);cardFilterContext.setState(new QuitFiltertable(cardFilterContext));} else {// Transition to CardAppType statecardFilterContext.setState(new CardAppTypeState(cardFilterContext));}}public List<Map<String, Object>> queryDbWithAcqIndexList(List<String> acqIndexList,DbManager dbManager) {String[] selectionColumns = {EmvDbHelper.acquirerId, EmvDbHelper.aidIndex};String[] columnsToSelect = {EmvDbHelper.aid, EmvDbHelper.aidPriority};List<Map<String, Object>> result = new ArrayList<>();// 初始化一个空数组String[] selectionValues = new String[2];// 遍历 acqIndexList,对每个字符串进行拆分并查询for (String acqIndex : acqIndexList) {// 进行拆分逻辑,这里示例取前两个字符if (acqIndex.length() >= 4) {// 取前两个字符作为第一个值String part1 = acqIndex.substring(0, 2);// 取后两个字符作为第二个值String part2 = acqIndex.substring(2, 4);// 将拆分后的值赋值给 selectionValues 数组selectionValues[0] = part1;selectionValues[1] = part2;// 进行查询并将结果添加到结果集List<Map<String, Object>> queryResult = dbManager.getColumnMapValuesWithCondition(selectionColumns, selectionValues, columnsToSelect);result.addAll(queryResult);} else {Logs.e(TAG,"acqIndex.length() "+ acqIndex.length());break;}}// 返回查询结果return result;}}
还有一个需求就是返回ReturnCode = CARDAPPNAV.
如果拿到选择应用的结果就返回并设置对应的ReturnCode
public boolean Appselect() {ContextAppSelete contextAppSelete = new ContextAppSelete();contextAppSelete.setState(new SelectAppState(contextAppSelete));try {while (true) {contextAppSelete.executeSelectFinalApp();if (contextAppSelete.getState() instanceof QuitFinalAppState) {contextAppSelete.executeSelectFinalApp();if (contextAppSelete.getErrorCode()!=0) {getCardOutput.setReturnCode(contextAppSelete.getReturnCodes());return false;} else {emv_candlist = contextAppSelete.getEmvCandlist();Logs.d(TAG, "emv_candlist.aid " + tools.hexString(emv_candlist.aid, 0, emv_candlist.aidLen));return true;}}}} catch (Exception e) {e.printStackTrace();}return false;}