Tam*_*rta 3 android version nfc open-mobile-api secure-element
据我了解,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应用程序包的版本信息:
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;
Run Code Online (Sandbox Code Playgroud)
为典型值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
}
}
Run Code Online (Sandbox Code Playgroud)又一,允许你区分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
}
Run Code Online (Sandbox Code Playgroud)从SEEK版本4.0.0开始,SEServiceOpen Mobile API框架的类公开了一个方法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
}
Run Code Online (Sandbox Code Playgroud)
此外,如果您有SEService对象的实例,则可以调用该getVersion()方法来查找已实现的Open Mobile API规范版本:
如果您的应用程序是根据SEEK <4.0.0编译的:
if (getVersion != null) {
String version = (String)getVersion.invoke(seService);
}
Run Code Online (Sandbox Code Playgroud)如果您的应用程序是针对SEEK> = 4.0.0编译的:
if (getVersion != null) {
String version = seService.getVersion();
}
Run Code Online (Sandbox Code Playgroud)请注意,尝试获取SEService类的实例可能会导致您首先发现的不良行为,因为SEService类的构造函数将自动启动与SmartcardService的连接.
与发现getVersion()方法类似,您也可以尝试在API中发现特定于某个版本的Open Mobile API规范的方法.例如,您可以测试方法的存在
public Channel openBasicChannel(byte[] aid, byte p2);
Run Code Online (Sandbox Code Playgroud)
在Session课堂上(org.simalliance.openmobileapi.Session).此方法是在规范3.0版中引入的.
但是,你应该知道,基于框架类的检测只会工作,如果你的应用程序使用了随目标设备的开放移动API框架类和并没有打包自己的相关框架类的版本.否则,您只会检测您打包到应用程序中的内容,而不是系统上可用的内容.
预装在设备上的Open Mobile API框架通常与同一设备上的后端(SMartcardService)兼容.由于您似乎存在版本冲突,因此您的应用程序可能会打包自己的Open Mobile API框架版本,该版本与目标Android版本和目标设备上安装的智能卡系统服务不兼容.这是你根本不应该做的事情.
| 归档时间: |
|
| 查看次数: |
2635 次 |
| 最近记录: |