3

私の知る限り、Open Mobile API はメーカーが作成した Android ROM にバンドルされています。Open Mobile API を多用する SDK を使用しており、一部のベンダーが Open Mobile API のバージョンが Android のバージョンと互換性のない ROM を作成していることがわかりました。これにより、上記の SDK を使用しようとすると、アプリケーションがクラッシュするという災害が発生します。SDK が新しいスレッドを開始し、そこでクラッシュするためです。これはすべて別のスレッドで実行されているため、ロジック全体を try-catch ブロックに入れることさえできません。

Android と Open Mobile API のバージョンを確認し、互換性がないかどうかを確認し、互換性がある場合は、それを必要とする機能を完全に無効にすることにしました。

プリインストールされている Open Mobile API のバージョンを確認する方法はありますか? ある場合、どうすればよいですか?

4

1 に答える 1

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;
    

    の典型的な値はversionName、「2.3.0」(versionCode = 1)、「2.4.0」(versionCode = 3)、「3.0.0」(versionCode = 4)、「3.1.0」(versionCode = 5)、および「 4.0.0" (バージョンコード = 8)。したがって、 SmartcardService がフォークされたSEEKの正確なバージョンを特定できます。

    残念ながら、いくつかの OEM (Samsung など) は、アプリケーション パッケージからバージョン情報を削除することを決定しました。したがって、これは期待するほど信頼できるものではありません。

  2. 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
        }
    }
    
  3. SEEK < 4.0.0 と SEEK >= 4.0.0 を区別できるさらに別の方法は、SmartcardService が SEEK 4.0.0 で導入されたアクセス許可 BIND_TERMINAL を保持しているかどうかを確認することです。

    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 以降SEService、Open 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
}

さらに、SEServiceオブジェクトのインスタンスがある場合は、メソッドを呼び出してgetVersion()、実装されている Open Mobile API 仕様のバージョンを見つけることができます。

  1. アプリケーションが SEEK < 4.0.0 に対してコンパイルされた場合:

    if (getVersion != null) {
        String version = (String)getVersion.invoke(seService);
    }
    
  2. アプリケーションが SEEK >= 4.0.0 に対してコンパイルされた場合:

    if (getVersion != null) {
        String version = seService.getVersion();
    }
    

クラスのインスタンスを取得しようとすると、クラスのコンストラクターがSmartcardService への接続を自動的に開始するSEServiceため、最初に見つけた望ましくない動作が発生する可能性があることに注意してください。SEService

メソッドの検出と同様にgetVersion()、Open Mobile API 仕様の特定のバージョンに固有の API のメソッドを検出することもできます。たとえば、メソッドの存在をテストできます

public Channel openBasicChannel(byte[] aid, byte p2);

Sessionクラス ( org.simalliance.openmobileapi.Session) で。このメソッドは、仕様のバージョン 3.0 で導入されました。

ただし、フレームワーク クラスに基づく検出は、ターゲット デバイスに同梱されている Open Mobile API フレームワーク クラスをアプリが使用し、関連するフレームワーク クラスの独自のバージョンをパッケージ化していない場合にのみ機能することに注意してください。そうしないと、システムで利用できるものではなく、アプリにパックしたものだけが検出されます。

デバイスにプリインストールされている Open Mobile API フレームワークは、通常、同じデバイスのバックエンド (SmartcardService) と互換性があります。バージョンの競合が発生しているように見えるため、ターゲットの Android バージョンおよびターゲット デバイスにインストールされているスマートカード システム サービスと互換性のない独自のバージョンの Open Mobile API フレームワークがアプリにパッケージ化されている可能性があります。これは絶対にやってはいけないことです。

于 2016-05-07T10:21:11.417 に答える