如何查看Android上的Open Mobile API版本?

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的版本?如果有,我该怎么办?

Mic*_*and 5

这取决于您实际想要找到的版本:SmartcardService系统组件的版本或Open Mobile API框架的版本.

查找SmartcardService系统应用程序的版本

  1. 最明显的方法是检查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(例如三星)决定从应用程序包中删除版本信息.因此,这不像人们预期的那样可靠.

  2. 另一种允许您区分基于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)
  3. 又一,允许你区分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)

查找Open Mobile API框架的版本

从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规范版本:

  1. 如果您的应用程序是根据SEEK <4.0.0编译的:

    if (getVersion != null) {
        String version = (String)getVersion.invoke(seService);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果您的应用程序是针对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版本和目标设备上安装的智能卡系统服务不兼容.这是你根本不应该做的事情.