如何查看Android上的Open Mobile API版本?
作者:互联网
据我了解,Open Mobile API与制造商创建的Android ROM捆绑在一起.我们正在使用大量使用Open Mobile API的SDK,并发现一些供应商创建了ROM,其中Open Mobile API的版本与Android版本不兼容.这会导致灾难,当我们尝试使用上述SDK时,应用程序崩溃.因为SDK启动了一个新线程,并在其上崩溃.我们甚至无法将整个逻辑放在try-catch块中,因为所有这些都在一个单独的线程中运行.
我们决定检查Android和Open Mobile API的版本,看看它们是否不兼容,如果是,则完全禁用需要它的功能.
有没有办法确定预装的Open Mobile API的版本?如果有,我该怎么办?
解决方法:
这取决于您实际想要找到的版本:SmartcardService系统组件的版本或Open Mobile API框架的版本.
查找SmartcardService系统应用程序的版本
>最明显的方法是检查SmartcardService应用程序包的版本信息:
final String SMARTCARD_SERVICE_PACKAGE = "org.simalliance.openmobileapi.service";
PackageInfo pi = getPackageManager().getPackageInfo(SMARTCARD_SERVICE_PACKAGE, 0);
String versionName = pi.versionName;
String versionCode = pi.versionCode;
versionName的典型值为“2.3.0”(versionCode = 1),“2.4.0”(versionCode = 3),“3.0.0”(versionCode = 4),“3.1.0”(versionCode = 5),以及“4.0.0”(versionCode = 8).因此,您可以确定SmartcardService分叉的确切版本SEEK.
不幸的是,一些OEM(例如三星)决定从应用程序包中删除版本信息.因此,这不像人们预期的那样可靠.
>另一种允许您区分基于SEEK版本的实现的方法< 4.0.0和SEEK版本> = 4.0.0是检查SmartcardService组件的intent过滤器:
final String SMARTCARD_SERVICE_PACKAGE = "org.simalliance.openmobileapi.service";
final String SMARTCARD_SERVICE_CLASS = "org.simalliance.openmobileapi.service.SmartcardService";
final String SMARTCARD_SERVICE_ACTION_V4 = "org.simalliance.openmobileapi.BIND_SERVICE";
final String SMARTCARD_SERVICE_ACTION_PRE4 = "org.simalliance.openmobileapi.service.ISmartcardService";
Intent intent = new Intent();
intent.setClassName(SMARTCARD_SERVICE_PACKAGE, SMARTCARD_SERVICE_CLASS);
intent.setAction(SMARTCARD_SERVICE_ACTION_V4);
ResolveInfo ri = getPackageManager().resolveService(intent, 0);
if (ri != null) {
// is version >= 4.0.0
} else {
intent.setAction(SMARTCARD_SERVICE_ACTION_PRE4);
ResolveInfo ri = getPackageManager().resolveService(intent, 0);
if (ri != null) {
// is version < 4.0.0
} else {
// is unknown version
}
}
>又一种方法,可以让你区分SEEK< 4.0.0和SEEK> = 4.0.0将检查SmartcardService是否拥有权限BIND_TERMINAL,这是SEEK 4.0.0中引入的权限:
final String SMARTCARD_SERVICE_PACKAGE = "org.simalliance.openmobileapi.service";
final String PERMISSION_BIND_TERMINAL = "org.simalliance.openmobileapi.BIND_TERMINAL";
if (PackageManager.PERMISSION_GRANTED == getPackageManager().checkPermission(PERMISSION_BIND_TERMINAL, SMARTCARD_SERVICE_PACKAGE)) {
// is version >= 4.0.0
} else {
// is version < 4.0.0
}
查找Open Mobile API框架的版本
从SEEK版本4.0.0开始,Open Mobile API框架的SEService类公开了一个方法getVersion(),它返回已实现的Open Mobile API规范的版本字符串(SEEK 4.0.0为“3.0”).因此,您可以查询该方法以查找已实现的Open Mobile API版本:
Class cls = org.simalliance.openmobileapi.SEService.class;
Method getVersion = null;
try {
getVersion = cls.getDeclaredMethod("getVersion");
} catch (NoSuchMethodException e) {}
if (getVersion != null) {
// probably SEEK >= 4.0.0
} else {
// probably SEEK < 4.0.0
}
此外,如果您有SEService对象的实例,则可以调用getVersion()方法来查找已实现的Open Mobile API规范版本:
>如果您的申请是针对SEEK< 4.0.0:
if (getVersion != null) {
String version = (String)getVersion.invoke(seService);
}
>如果您的应用程序是针对SEEK> = 4.0.0编译的:
if (getVersion != null) {
String version = seService.getVersion();
}
请注意,尝试获取SEService类的实例可能会导致您首先发现的不良行为,因为SEService类的构造函数将自动启动与SmartcardService的连接.
与发现getVersion()方法类似,您也可以尝试在API中发现特定于某个版本的Open Mobile API规范的方法.例如,您可以测试方法的存在
public Channel openBasicChannel(byte[] aid, byte p2);
在Session类中(org.simalliance.openmobileapi.Session).此方法是在规范3.0版中引入的.
但是,您应该知道,只有当您的应用程序使用目标设备附带的Open Mobile API框架类并且不打包自己版本的相关框架类时,基于框架类的检测才有效.否则,您只会检测您打包到应用程序中的内容,而不是系统上可用的内容.
预装在设备上的Open Mobile API框架通常与同一设备上的后端(SMartcardService)兼容.由于您似乎存在版本冲突,因此您的应用程序可能会打包自己版本的Open Mobile API框架,该框架与目标Android版本和目标设备上安装的智能卡系统服务不兼容.这是你根本不应该做的事情.
标签:android,version,nfc,open-mobile-api,secure-element 来源: https://codeday.me/bug/20190829/1758544.html