これは、実際に調べたいバージョン (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" (バージョンコード = 8)。したがって、 SmartcardService がフォークされたSEEKの正確なバージョンを特定できます。
残念ながら、いくつかの OEM (Samsung など) は、アプリケーション パッケージからバージョン情報を削除することを決定しました。したがって、これは期待するほど信頼できるものではありません。
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
}
}
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 仕様のバージョンを見つけることができます。
アプリケーションが SEEK < 4.0.0 に対してコンパイルされた場合:
if (getVersion != null) {
String version = (String)getVersion.invoke(seService);
}
アプリケーションが 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 フレームワークがアプリにパッケージ化されている可能性があります。これは絶対にやってはいけないことです。