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

如何在Android上检查Open Mobile API的版本?,android,version,nfc,open-mobile-api,secure-element,Android,Version,Nfc,Open Mobile Api,Secure Element,据我所知,开放式移动API与制造商创建的Android ROM捆绑在一起。我们正在使用一个大量使用开放式移动API的SDK,并发现一些供应商创建了ROM,其中开放式移动API的版本与Android的版本不兼容。这导致了一场灾难,当我们尝试使用上述SDK时,应用程序崩溃。因为SDK启动了一个新线程,并在其上崩溃。我们甚至不能将整个逻辑放在一个try-catch块中,因为所有这些都在一个单独的线程中运行 我们决定检查Android和OpenMobile API的版本,看看它们是否不兼容,如果不兼容,

据我所知,开放式移动API与制造商创建的Android ROM捆绑在一起。我们正在使用一个大量使用开放式移动API的SDK,并发现一些供应商创建了ROM,其中开放式移动API的版本与Android的版本不兼容。这导致了一场灾难,当我们尝试使用上述SDK时,应用程序崩溃。因为SDK启动了一个新线程,并在其上崩溃。我们甚至不能将整个逻辑放在一个try-catch块中,因为所有这些都在一个单独的线程中运行

我们决定检查Android和OpenMobile API的版本,看看它们是否不兼容,如果不兼容,则完全禁用所需的功能


有没有办法确定预安装的Open Mobile API的版本?如果有,我该怎么做?

这取决于您实际想要了解的版本:SmartcardService系统组件的版本或Open Mobile API framework的版本

查找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)。因此,您可以确定智能卡服务的确切版本

    不幸的是,一些原始设备制造商(如三星)决定从应用程序包中删除版本信息。因此,这并不像人们预期的那样可靠

  • 允许您区分基于SEEK版本<4.0.0和SEEK版本>=4.0.0的实现的另一种方法是检查SmartcardService组件的意图过滤器:

    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
        }
    }
    
    此外,如果您有
    SEService
    对象的实例,则可以调用
    getVersion()
    方法来查找实现的开放式移动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中发现特定于特定版本的OpenMobile API规范的方法。例如,您可以测试该方法是否存在

    public Channel openBasicChannel(byte[] aid, byte p2);
    
    会话
    类(
    org.simalliance.openmobileapi.Session
    )中。该规范的3.0版中引入了此方法

    但是,您应该知道,只有当您的应用程序使用目标设备附带的开放式移动API框架类,并且没有打包其自身版本的相关框架类时,基于框架类的检测才会起作用。否则,您将只检测您打包到应用程序中的内容,而不检测应用程序上可用的内容系统


    预装在设备上的开放式移动API框架通常与同一设备上的后端(SMartcardService)兼容。由于您似乎存在版本冲突,因此您的应用程序可能会打包自己的开放式移动API框架版本,该版本与目标设备上安装的目标Android版本和智能卡系统服务不兼容这是你不应该做的事。

    谢谢!非常全面的回答。给我点时间消化,我会接受的。谢谢!我现在才有时间来解决这些问题,我检查了你的答案,效果很好!
    if (getVersion != null) {
        String version = seService.getVersion();
    }
    
    public Channel openBasicChannel(byte[] aid, byte p2);