開発マニュアル

バージョン

改訂日

改訂内容

バージョン1.0.2

2020/4/7

本SDKを適用できるデバイスタイプを追加

バージョン1.0.3

2020/5/12

ドアアクセス機能の紹介を追加

バージョン1.2.0

2020/10/14

顔の温度検知機能の紹介を追加

バージョン2.0.0

2021/02/05

カメラの呼び出しプロセス、およびサーモカメラの呼び出しプロセスの紹介を追加。顔の温度検知機能に関連するインターフェースの記載を更新

バージョン2.0.0

2021/04/10

デバイス名を修正

バージョン2.1.0

2021/04/30

誤植を修正

Package名を修正

機種別の温度検知バージョンを追記

Thunder SDK開発マニュアル

Thunder SDK(以下、「SDK」)は、AI顔認証アルゴリズムおよびその派生機能をベースにした Android 向けSDKで、JCVインテリジェントハードウェアデバイス(以下、「ハードウェアデバイス」)を実行キャリアとして採用します。生体検知、1:N顔認証、1:1顔認証、顔温度検知、マスク検知、アクセスコントロールなどの機能を迅速に開発するために使用できます。

本ドキュメントは主に開発エンジニアを対象として書かれており、SDKのインテグレーション手順や機能の使用方法を説明しています。

SDKのビジネス機能について

SDKはデバイスのカメラで顔をキャプチャして顔認証を行うといった、オフラインでの顔認証に使用できます。一般的な流れは次のとおりです。

一般的なプロセスを踏まえると、顔の照合には1対1の場合と1対Nの場合があるため、1:1認証と1:N認証に細分化されます。それぞれ異なるシナリオで使用され、1:1認証は後ほど定義するような1:NでNを1と設定する場合とは異なります。

カメラの呼び出し

カメラに素早くアクセスしてプレビューコールバックデータを取得したり、カメラのライフサイクルを管理するメソッドをカプセル化など、カメラのステータスを監視する機能をサポートしています。

サーマルイメージングシステムの呼び出し

  • 交通現場で使用されるサーマルイメージングシステムの特徴として、サーマルイメージングシステムのプレビューおよびデータのコールバック、ライフサイクルの管理、ステータスの監視、ホットプラグ後の自動接続などが挙げられます。

  • 対応するサーマルイメージングシステムのモデルは、Arrow、Guide120、Guide256です。

1:1認証

  • 「1:1認証」は、「あなたがあなたであること」を証明するプロセスです。具体的には、特定の身元情報をシステムが保持している場合、カメラ画面に映っている人物の顔情報と保存している身元情報が一致するかを判断します。

  • 銀行、携帯キャリアショップでの本人確認や駅・空港、ホテル、インターネットカフェなどで認証が必要な状況など、個人の認証が必要とされるシナリオでよく使われる認証操作です。

1:N認証

「1:N認証」とは、認証対象の顔画像セットをローカルの顔フィーチャーライブラリに登録しておき、カメラが顔情報を取得した際にライブラリ内の顔フィーチャーセットと比較することで、認証結果を導き出します。

  • コミュニティやオフィスビル、学校などでのアクセスコントロールや勤怠確認、複数人を認証する必要がある状況でよく使われます。

マスク検知

「マスク検知」は、カメラでキャプチャした顔情報を解析することで、マスクを着用しているかを迅速に検知します。病院や製造工場、粉塵の多い建設現場など、マスクが必要とされる場面で活用されています。

サーバーサイドの1:N認証

前述した一般的な1:N認証プロセスにおいては、顔の照合はローカルでもリモート(HTTPネットワークリクエスト経由)でも実行可能です。リモートで実行する場合、比較ロジックをユーザー自身が実装する必要があり、本機能の実装には顔認証バックエンドサーバーがあることが前提となります。

ドアアクセス機能

「ドアアクセス機能」は、SDKのドアアクセスデバイスのコントロール機能を指します。ハードウェアデバイスによって、ドアアクセスデバイスのサポート範囲が異なります。対応関係を説明するために、次のように概念を定義します。

  • ドアアクセスデバイス」 - SenseTimeのハードウェアデバイスに含まれるハードウェアアクセサリーや、ハードウェア拡張インターフェースにより接続して使用できる周辺機器などのすべてのデバイスの総称。

    • ハードウェアアクセサリ:スクリーンバックライト、IRフィルライト、照明センサー、距離センサー、ブザー、ローカルリレー、ラウドスピーカー、強制解体アラートボタンなど。

    • 周辺機器:ドアオープンボタン、消防アラートシグナル、ドアマグネット、ドアベル、アラート、Wiegandカードリーダー、ネットワークリレー、Wiegandドアオープンコントローラーなど。

  • ドアアクセス機能」 -主に「ドアアクセスデバイス」を使用することを指し、ローカルリレーによるドアのオープン、Wiegandコントローラーによるドアのオープン、スクリーンフィルライトの消灯、ドアベルの鳴動制御、距離センサーによる人体の距離検知などの機能を含む。

SDKの「ドアアクセス機能」のサポート範囲は、ハードウェアデバイスによって異なります(次の表ではハードウェアの観点ではなく、SDKでの対応の観点でのみ記載しています)。

デバイスモデル

オープンボタン

消防アラートシグナル

ドアセンサー

ドアベル

アラート

SensePass

SenseThunderE-mini

SenseThunderE

SenseThunderAir

デバイスモデル

Wiegandリーダー

Wiegandコントローラー

ローカルリレー

ネットワークリレー

SensePass

SenseThunderE-mini

SenseThunderE

SenseThunderAir

デバイスモデル

ブザー

赤外線人感センサー

距離センサー

照明センサー

IRフィルライト

SensePass

×

SenseThunderE-mini

×

SenseThunderE

×

×

SenseThunderAir

×

×

デバイスモデル

RGBフィルライト

スクリーンバックライト

スピーカー

盗難アラートボタン

NFCリーダー

SensePass

×

×

×

SenseThunderE-mini

×

×

×

SenseThunderE

×

×

SenseThunderAir

×

×

本ドキュメントでは、説明のために以下のように定義しています。

  • Passアクセスコントロール機能:PassとThunderシリーズ(上記デバイスモデル)のその他のデバイスで使用されるアクセスコントロール機能のこと。

なお、アクセスコントロール機能の使用について説明する場合、以下のように異なるデバイスにおける違いにご注意ください。

QRコード認証

「QRコード認証」とは、QRコードの内容を解析する機能のことで、QRコードの認証が必要なシナリオで使用されます。SDKには2つのコーデックライブラリZXingZBarが組み込まれており、使用時に選択できます。

顔の温度検知

「顔の温度検知」とは、顔認証機能と温度検知モジュールを介して、顔および熱力学線図のデータをアルゴリズムにより処理し、顔の温度を取得することです。現在サポートされている温度検知モジュールは、Arrowモジュール、Guide120モジュール、およびGuide256モジュールです。なお、顔の温度値は、周囲の温度、モジュールのモデル、使用方法などによって異なる場合がありますのでご注意ください。

SDKに適したデバイスについて

デバイスモデル

デバイスカテゴリ

プラットフォーム

Android バージョン

カメラタイプ

SensePass

Pass シリーズ

RK3399-arm64-v8a

Android 7.1

RGB 顔 + IR

SenseThunderE

Thunder シリーズ

RK3399-arm64-v8a

Android 7.1

RGB 顔 + IR + サーモ

SenseThunerE-Mini

Thunder シリーズ

RK3399-arm64-v8a

Android 7.1

RGB 顔 + IR + サーモ

SenseThunderAir

Thunder シリーズ

RK3399-arm64-v8a

Android 7.1

RGB 顔 + IR + サーモ

顔カメラによる撮影について

カメラによる撮影について説明するために、次のように定義します。

  • 水平方向の画像: 撮影した写真の幅が、高さよりも広いことを意味します。

  • 垂直方向の画像: 撮影した写真の幅が、高さよりも狭いことを意味します。

  • 画像のミラーリング: カメラ画像において、被写体の実際の移動方向と写真の表示方向が逆になっていることを示します。人が左方向に歩いている場合、プレビュー画面では右に向かって進んでいるように表示されます。

  • 顔の方向: カメラ画像において顔が向いている方向を指し、次のように左から順に上向き、下向き、左向き、右向きとなります。

次の表では、特定のデバイスモデルに対応する顔カメラの画像の特性を示します。

デバイスモデル

撮影方向

顔の方向

画像のミラーリング

SensePass

垂直方向の画像

左向き

いいえ

SenseThunderE

垂直方向の画像

左向き

いいえ

SenseThunderE-Mini

垂直方向の画像

左向き

いいえ

SenseThunderAir

垂直方向の画像

左向き

いいえ

アクセス手順

SDKは、.aarパッケージ.soファイルアルゴリズムモデルファイルサンプルプロジェクト開発ドキュメントを含むzip形式のパッケージファイルとして提供されます。SDKは次の環境で動作します。

環境項目

説明

デバイス

SensePass, SenseThunderE, SenseThunderE-Mini, SenseThunderAir

Android バージョン

Android 7.1以上のバージョンと互換性があります。

SDKのアクティベーション

インテリジェントハードウェアでアプリケーションを動作させるためには、承認された.lic形式のライセンスファイルを申請する必要があります。

IDE 環境

Android Studio 3.5.3 以上のバージョン

インテグレーションの開始

  1. 次の図のように、.aarファイルをproject libsフォルダにコピーします。

  1. 次の図のように、デバイスタイプに応じて、zipパッケージのmodel fileフォルダ内の対応するモデルファイルを選択します。

デバイスタイプ

対応するモデル

Pass シリーズ

model フォルダのルートにある .model ファイル、および pass_extフォルダ内のすべてのファイル

Thunder シリーズ

model フォルダのルートにある .model ファイル、および pass_extフォルダ内のすべてのファイル

zipパッケージ内の対応するモデルファイルを、実際のプロジェクトのassetsおよびmodelフォルダにコピーします。

  1. 次の図に示すように、デバイスタイプに応じて、パッケージのso libraryフォルダ内の対応するsoライブラリを選択します。

デバイスタイプ

対応する so

Pass シリーズ

Pass-series-rk3399-general(arm64-v8a のみ)

Thunder シリーズ

Pass-series-rk3399-general(arm64-v8a のみ)

次に、フォルダ内のsoを/src/main/jniLibsフォルダにコピーします。

  1. build.gradleファイルに次の設定を加えます。

android {
     ...
     compileOptions {
         sourceCompatibility JavaVersion.VERSION_1_8
         targetCompatibility JavaVersion.VERSION_1_8
     }
}
dependencies {
    implementation files('libs/Thunder-android-vx.x.x.aar')
    //SDKで必要なサードパーティのライブラリ
    implementation 'com.alibaba:fastjson:1.2.70'
    implementation 'com.facebook.conceal:conceal:2.0.1@aar'
    implementation 'com.google.zxing:core:3.3.3'
    implementation 'com.github.open-android:pinyin4j:2.5.0'
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.okhttp3:okhttp:4.8.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:4.8.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'com.liulishuo.okdownload:okdownload:1.0.7'
    implementation 'com.liulishuo.okdownload:okhttp:1.0.7'
    implementation 'com.liulishuo.okdownload:sqlite:1.0.7'
}
  1. AndroidManifest.xml ファイルに、次のように権限の宣言を追加します。

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.NFC" />
  1. 次のサンプル画像のように、.lic形式のライセンスファイルをassetsフォルダにコピーします(サンプル内には、テストにのみ使用できるデバッグ用のライセンスファイルが提供されています。正式な本番環境用には、別途ライセンスファイルを申請する必要があります)。

サンプルプロジェクト

サンプルプロジェクトは、Android Studioで開くことができます。ドキュメントに従って、aar、model、soやその他のファイルを対応するフォルダにコピーし、PassシリーズやThunderシリーズのハードウェアデバイスでデバッグを実行してください。サンプルプロジェクトは、主に1:N認証、1:1照合、マスク検知、アクセスコントロール、その他の機能の使用方法を示します。

SDKの使用方法

本セクションでは、SDKの主要なAPIとプロセスの使用方法を中心に説明します。

SDKの初期化

SDKを使用する前に、aar、model、so、.licの各ファイルが正しく保存され、設定されていることを確認します。ファイルの準備が完了したら、次の手順で初期化を行います。

//SDKを初期化します
WuKong.init(this);

アクティベーションは初期化に成功した後に行うことができます。

//SDKで使用されているモデルを指定します。ここでは、SensePass デバイスでの初期化を例にとります。詳細については、サンプルコードをご覧ください。
model.mMode = SDKMode.PASS;
model.mAlignmentModel = "model/M_Align_occlusion_106_1.20.0.model";
model.mSmallDetectModel = "model/M_Detect_Hunter_LargeFaceSelfie_Gray_11.2.0.model";
model.mVerifyModel = "model/M_Verify_Mobilenetv2Pruned_BGR_Surveillance_4.13.0_v2_weak.model";
model.mDoubleHackModel = "model/pass_ext/M_Liveness_Antispoofing_Binocular_3.28.0.model";
model.mVerifyFinanceModel = "model/M_Verify_Mobilenetv2Pruned_BGR_Surveillance_4.13.0_v2_weak.model";
model.mAttributeModel = "model/M_Attribute_MTNet_2.1.1.model";

// assets ディレクトリ内のライセンスファイルの名前
String licenseName = "sensepass.lic";
String productName = null;

WuKong.auth(licenseName, productName, model, new IAuthCallback(){
            @Override
            public void onSuccess(){
                // アクティベーションに成功
            }

            @Override
            public void onFail(int code, String errMsg){
                // アクティベーションに失敗
            }
        });

通常、SDKのアクティベーション成功後は、アプリケーションを終了する前に解放操作を実行する必要はありません。具体的にアプリケーションを再起動する必要がある場合、次のようにアプリケーションの終了時にSDKリソースを解放することができます。

//SDKリソースを解放します
WuKong.release();

カメラの呼び出し

SDKのCameraTextureViewおよびCameraManagerクラスを使用すると、カメラのライフサイクルや関連するプレビュー操作を簡単に管理することができます。以下は、顔カメラ(RGB)を使用した使い方を紹介した例です。CameraTextureViewは、次のようにレイアウトファイルで使用できます(全画面プレビュー)。

<com.sensetime.camera.view.CameraTextureView
        android:id="@+id/camera_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:scalableType="centerCrop" />

次にカメラの初期化を行います。詳細については、下記コードをご参照ください。プレビュー解像度は1280✕720ピクセルを推奨します。

CameraTextureView mCameraView = findViewById(R.id.camera_view);
Camera.PreviewCallback mRgbCallback = new Camera.PreviewCallback(){
        @Override
        public void onPreviewFrame(byte[] data, Camera camera){
            // Identify Manager に渡すことができる、データをプレビューするコールバック
            // IdentifyManager.getInstance().handleRgbData(data);
        }
};

// 顔カメラの設定を例にとります
CameraManager faceCameraManager = CameraManager.getInstance(CameraUtils.getFaceCameraIndex());
// データをプレビューするコールバックを追加します
faceCameraManager.addPreviewCallbackWithBuffer(mRgbCallback);
// カメラを有効化します
faceCameraManager.openCamera(getApplicationContext());
// プレビューの幅や高さ、顔の方向など、プレビュー関連のパラメーターを設定します
faceCameraManager.initParameters(1280, 720, 0, mCameraView.getSurfaceTexture());

次のように、カメラのライフサイクルを制御します。

// プレビューを開始します
faceCameraManager.startPreview();

// プレビューを停止します
faceCameraManager.stopPreview();

// カメラを解放します
faceCameraManager.releaseCamera();
faceCameraManager.setPreviewTexture(null);
faceCameraManager.removePreviewCallbackWithBuffer(mRgbCallback);
faceCameraManager.setCameraLifecycleCallback(null);
faceCameraManager.setCameraStatusCallback(null);
faceCameraManager.setCameraExceptionHandler(null);
faceCameraManager.setCameraDataUpdateCallback(null);

サーマルイメージングシステムの呼び出し

サーモカメラの関連インターフェースを呼び出す前に、サーモカメラのインスタンスを取得してください。SDKではサーマルイメージングシステムの様々なインスタンスを取得するために、次のようにTemperatureCameraFactoryが提供されています。

// サーマルイメージングシステムタイプを取得します
CameraType cameraType = TemperatureCameraUtils.getCameraType();
// カメラタイプに応じて、関連するサーマルイメージングシステムのインスタンスを取得します
ITemperatureCamera temperatureCamera = TemperatureCameraFactory.getTemperatureCamera(cameraType);

サーマルイメージングシステムの設定を初期化します。

Initialize Thermal imaging system
temperatureCamera.initCamera(context);
// サーマルイメージングシステムの関連パラメーターを設定します(初期化後に実行する必要があります)
temperatureCamera.setConfig(config);
// シャッターを自動的に有効にするかどうかを設定します。デフォルトではtrueです(シャッターを有効にすると温度検知の精度が向上しますが、デバイスの耐用年数が短くなります)。
temperatureCamera.setAutoShutterEnable(true);

熱力学線図、および温度データのコールバックを追加します。

ITemperaturePreviewDataCallback dataCallback = new ITemperaturePreviewDataCallback(){

            @Override
            public void onTemperaturePreviewData(Bitmap temperatureBitmap, float[] temperatureValue, int width, int height){
                    // 熱力学線図および温度データのコールバック
            }
        };
// データコールバックを追加します
temperatureCamera.addTemperaturePreviewDataCallback(dataCallback);
// データが使用されていない場合、コールバックを削除します。
temperatureCamera.removeTemperaturePreviewDataCallback(dataCallback);
// 温度データは、摂氏で表示されないことに注意する必要があります。摂氏でデータを取得する場合は、次の方法で求めることができます。
temperatureCamera.getCentigradeFromTemperatureData(temperatureValue);
// または一括で変換することも可能です。
temperatureCamera.matrixTemperature(temperatureValue,width,height,distance,x,y,w,h,tempArray);

サーマルイメージングシステムのステータスを部分的に取得します。

// サーマルイメージングシステムから体温を取得します
temperatureCamera.getCameraBodyTemperature();

サーマルイメージングシステムのライフサイクルを管理します。

// サーマルイメージングシステムのプレビューを開始します
temperatureCamera.startPreview(textureView);
// サーマルイメージングシステムのプレビューを停止します
temperatureCamera.stopPreview();
// サーマルイメージングシステムのカメラリソースを解放します
temperatureCamera.releaseCamera();

SDKでは上記に加えて、サーマルイメージングシステムを操作するために多数の方法が提供されています。次の操作方法は一例です。

// シャッターを有効にします(シャッターを有効にすると温度検知の精度が向上しますが、デバイスの耐用年数が短くなります)
temperatureCamera.shutter();

1:N認証の流れ

顔認証のビジネスプロセスには、カメラの管理、顔特徴量ライブラリの作成、生体検知、顔比較、結果の処理などのいくつかのステップがあります。ここでは「1:N認証」を例に、SDKの使用方法を説明します。

顔フィーチャーライブラリの作成

1:N認証では顔フィーチャーを検索するための「データベース」として、顔フィーチャーライブラリが必要です。そのため、処理を開始する前にライブラリを構築する必要があります。SDKには顔フィーチャーライブラリを作成するためのFeatureManagerProxyが用意されており、次のように簡単に利用することができます。

// 正面からの鮮明な写真1枚
Bitmap avatar = BitmapFactory.decode(R.id.avatar);
int userId =123;

if(avatar != null){
      // 写真から顔フィーチャーを取得します
      byte[] feature = FeatureManagerProxy.getInstance().getFeature(avatar);
      // フィーチャーライブラリを挿入します(ネイティブメモリ)。データの永続化には、上位ビジネス層での処理が必要です。
      int result = FeatureManagerProxy.getInstance().insert(userId, feature);
      if(result == 0){
            Log.d(TAG, "Face Feature Inserted Successfully");
      }
}

// 人物のフィーチャーを削除します
int result = FeatureManagerProxy.getInstance().delete(userId);
if(result == 0){
      Log.d(TAG, "Face Feature Deleted Successfully");
}

N個の顔フィーチャー(最大は5W)をフィーチャーライブラリに挿入できます。構築が完了したら、人物認証プロセスの際にIdentify Managerは'FeatureManagerProxy'の挿入された顔フィーチャーデータを自動的に取得し、認証を行います。

カメラプレビューの開始

「カメラの呼び出し」を参照して、RGBカメラをオンにします。生体検知が有効になっている場合はIRカメラを再度オンにし、プレビューデータがIdentify Managerに渡されるように、データのプレビューコールバックを次のように変更する必要があります。

Camera.PreviewCallback mRgbCallback = new Camera.PreviewCallback(){
        @Override
        public void onPreviewFrame(byte[] data, Camera camera){
            // Identity Manager に RGB データのプレビューコールバックを転送します
            IdentifyManager.getInstance().handleRgbData(data);
        }
};
Camera.PreviewCallback mIrCallback = new Camera.PreviewCallback(){
        @Override
        public void onPreviewFrame(byte[] data, Camera camera){
            // Identity Manager に IR データのプレビューコールバックを転送します
            IdentifyManager.getInstance().handleIrData(data);
        }
};

Identify Manager の開始

Identify Managerには「1:N」「1:1」および「サーバーサイド1:N」認証処理が組み込まれており、モードを切り替えることで内部の認証ロジックを変更することができます。Identify Manager のモードは次のとおりです。

  • VerifyModeEnum.MODE_1_N: 1:N認証モード。1:N認証処理に対応。

  • VerifyModeEnum.MODE_1_1: 1:1認証モード。1:1認証処理に対応。

  • VerifyModeEnum.MODE_SERVER_1_N: サーバーサイド1:N認証モード。サーバーサイドの1:N認証処理に対応。

使用前に、次のように設定します。

 // デバイスのハードウェア環境に応じた、画像関連の設定を構成します
ImageConfig imageConfig = new ImageConfig.Builder()
          .previewW(1280)
          .previewH(720)
          .faceOrientation(FaceOrientation.UP)
          .pixelFormat(MidPixelFormat.NV21)
          .build();


// 初期化します
IdentifyManager.getInstance().init(imageConfig,identifyCallback);

// Identify Manager の認証モードを設定します
IdentifyManager.getInstance().setVerifyMode(VerifyModeEnum.MODE_1_N);
// 結果のコールバックを設定します
IdentifyManager.getInstance().setIdentifyCallback(identifyCallback);

初期設定の完了後、次のように Identify Managerのオンまたはオフを切り替えることで、認証を制御することができます。

//認証を有効にします
IdentifyManager.getInstance().start();

//認証を停止します
IdentifyManager.getInstance().stop();

// Identify Manager を解放します
IdentifyManager.getInstance().release();

認証処理の詳細はパラメーターによって制御することができます。Identify Managerのパラメーターは特定のビジネスシナリオに応じて、次のように個別に設定できます(下記コードアノテーションでは、PassやThunderシリーズと異なるシリーズの注意事項がある場合、適宜読み飛ばしてください)。

IdentifyConfig identifyConfig = IdentifyManager.getInstance().getIdentifyConfig();
IdentifyConfig.hasLiveness = true; // 生体検知を有効にします
identifyConfig.isSingleLiveness = DeviceInfoUtils.isSenseIDProduct();   // モノキュラカメラによる生体検知では、本項目はIDシリーズのデバイスのみで有効にする必要があります
identifyConfig.isSenseGateConfig = DeviceInfoUtils.isSenseGateProduct();  // 使用しているデバイスが SenseGateシリーズの場合のみ、オンにします
identifyConfig.isContinueVerify = true; // IdentifyConfig.isContinueVerify = true; / / 連続して認証するかどうか。有効にすると、連続して認識されます(顔がカメラの視野に入っている必要があります)。continueVerifyIntervalTimeパラメーターと一緒に使用します。
identifyConfig.continueVerifyIntervalTime = 3000L;  // 同じ顔を続けて認証する間隔。isContinueVerifyがtrueに設定されている場合に有効になります。
identifyConfig.hasTemperatureDetection = false;
identifyConfig.isServerVerify = false;
IdentifyManager.getInstance().setIdentifyConfig(identifyConfig);

// 修正点は次のとおりです。1:N認証で、照合閾値が0.83fに、生体フィルタリング閾値が0.95f(超える場合は非生体になります)に変更されました。顔認証の最小値は、100ピクセルです。
ThresholdConfig thresholdConfig = IdentifyManager.getInstance().getThresholdConfig();
thresholdConfig.verifyScore = 0.83f;
thresholdConfig.livenessScore = 0.95f;
thresholdConfig.faceMinWidth =100;
thresholdConfig.verifyAreaRect = new RectF(0, 0, mPreviewHeight, mPreviewWidth);
IdentifyManager.getInstance().setThresholdConfig(thresholdConfig);

認証結果の処理

Identify Managerはコールバックインターフェースにより、認証結果を上位ビジネス層に送信します。上位ビジネス層では、次のようにコールバックインターフェースで結果を処理してください。

IIdentifyResultCallback identifyCallback = new IIdentifyResultCallback(){

    @Override
    public void onDrawFaces(@Nullable List<FaceInfo> list){
        // 顔検知のコールバック。顔設定フレームの描画に使用されます。
        // 認証が一時停止されても、このコールバックは発生することに注意する必要があります。その場合、プロセス内で顔はトラッキングされているものの、認識されていない状態となります。
    }

    @Override
    public void onClearScreen(){
        // スクリーンを消去するコールバック。カメラの視野に顔が入っていない場合、本コールバックでスクリーンを消去します。
    }

    @Override
    public void onUnknown(float faceW){
                // 顔が大きすぎたり、小さすぎたりして、生体であるかどうか判断できない場合は、本メソッドで通知されます
    }

    @Override
    public void onIdentifyResult(List<FrameIdentifyResult> frameIdentifyResults){
                //認証結果のコールバック
    }
};

// 結果を設定するコールバック
IdentifyManager.getInstance().setIdentifyCallback(identifyCallback);

結果のコールバックが不要な場合は、次のようにNULLを設定します。

// 結果のコールバックを削除します
IdentifyManager.getInstance().setIdentifyCallback(null);

この時点で「1:N認証」プロセスが構築されています。

1:1認証処理

上記に説明したとおり、「1:N認証」処理の場合、Identify ManagerはVerifyModeEnum.MODE_1_Nモードを使用します。顔の「1:1認証」処理の場合、次に示す方法で「1:1認証」モードに切り替える必要があります。

// Identify Managerの初期化は、1:N認証の場合と同様です
// Identify Managerを1:Nから1:1に切り替える場合、まず単一の認証機能を設定してから、モードを切り替える必要があります

Bitmap singleTarget = BitmapFactory.decodeResource(getResource(), R.mipmap.face);
boolean setupResult = IdentifyManager.getInstance().setIdentifyTarget(singleTarget);
// Identify Managerの認証モードを設定します。設定する前に、各認証機能が正常に設定されているか確認します。
if(setupResult){
    IdentifyManager.getInstance().setVerifyMode(VerifyModeEnum.MODE_1_1);
}

サーバーサイドの1:N認証

リモートサーバー上で認証処理を実行する場合は、Identity Managerの設定を変更して、1:N認証に基づいたサーバーサイド認証を有効にする必要があります。次に、IServerVerifyAction クラスを使用して、認証ロジックを実装します。具体的な使用方法は次のとおりです。

//1. サーバー認証モードを有効にします
IdentifyManager.getInstance().setVerifyMode(VerifyModeEnum.MODE_SERVER_1_N);

//2. サーバー認証操作を実行します
IServerVerifyAction serverVerify = new IServerVerifyAction(){
        @Override
        public <T extends FaceSearchResult> T verify(@NonNull byte[] cameraData, byte[] feature, @Nullable FaceInfo rgbFace,int width, int height){

              // HTTPリクエストを介してデータをアップロードし、認証結果を取得します(適切なリクエストのタイムアウトを設定するようにご注意ください)
            // ..コード

            // 次の例のように、顔の検索結果を構築して取得します
            FaceSearchResult result = new FaceSearchResult();
            result.score = 0.93f;
            result.userID =12345;

            return(T)result;
        }
};

// 3. サーバー認証操作を設定します
IdentifyManager.getInstance().setServerVerifyAction(serverVerify);

マスク検知

「1:N」「1:1」および「サーバーサイドの1:N」認証に基づいてマスク検知を有効化すると、認証結果から対応するマスク検知結果を取得します。マスク検知機能が有効になっていない場合でも、デフォルトでマスク検知結果はtrueと返されます。次の手順で検知機能を有効化します。

// マスク着用認証を有効化します
IdentifyConfig identifyConfig = IdentifyManager.getInstance().getIdentifyConfig();
identifyConfig.isOpenWearMaskIdentify = true;
IdentifyManager.getInstance().setIdentifyConfig(identifyConfig);

// 認証結果のコールバックインターフェースを介して、顔認証結果を取得します
IIdentifyResultCallback identifyCallback = new IIdentifyResultCallback(){

    @Override
    public void onDrawFaces(@Nullable List<FaceInfo> list){
        // 顔検知のコールバック。顔設定フレームの描画に使用されます。
        // 認証が一時停止されても、このコールバックは発生することに注意する必要があります。その場合、プロセス内で顔はトラッキングされているものの、認識されていない状態となります。
    }

    @Override
    public void onClearScreen(){
        // スクリーンを消去するコールバック。カメラの視野に顔が入っていない場合、本コールバックでスクリーンを消去します。
    }

    @Override
    public void onUnknown(float faceW){
                // 顔が大きすぎたり、小さすぎたりして、生体であるかどうか判断できない場合は、本メソッドで通知されます
    }

    @Override
    public void onIdentifyResult(List<FrameIdentifyResult> frameIdentifyResults){
                //認証結果のコールバック
      for(int i = 0; i < frameIdentifyResults.size(); i++){
            FrameIdentifyResult frameIdentifyResult = frameIdentifyResults.get(i);
            List<FaceIdentifyResult> faceIdentifyResults = frameIdentifyResult.faceIdentifyResults;
            for(int j = 0; j < faceIdentifyResults.size(); j++){
                FaceIdentifyResult faceIdentifyResult = faceIdentifyResults.get(j);
                  // 顔認証結果を取得します
                  boolean mask = faceIdentifyResult.isMask();
            }
        }
    }
};

// 結果を設定するコールバック
IdentifyManager.getInstance().setIdentifyCallback(identifyCallback);

顔の温度検知

顔の温度検知機能を使用する前に、「1:N」「1:1」および「サーバーサイド1:N」認証に基づいて、次のようにIdentity Managerの温度検知設定の項目を有効にする必要があります。

IdentifyConfig identifyConfig = IdentifyManager.getInstance().getIdentifyConfig();
identifyConfig.hasTemperatureDetection = true;    // 温度検知を有効にします
IdentifyManager.getInstance().setIdentifyConfig(identifyConfig);

注意すべき点として、温度検知機能が有効な場合、Identify Managerが正常に動作するためには温度データが必要なことです。温度データが取得されるまでは認証は行われませんが、顔のトラッキングは正常に行われます。また、温度検知機能が有効な場合は次のように顔認証用の枠を設定し、正面からの顔の角度が鋭く表示されるようにして、カメラの視野の中央で顔を認証することを推奨します。これにより、顔認証および温度検知の精度が向上します。

ThresholdConfig thresholdConfig = IdentifyManager.getInstance().getThresholdConfig();
thresholdConfig.faceMinWidth = 200; // 温度検知では、近距離で、顔の幅を大きめに設定する必要があります
thresholdConfig.pitch = 20;   // 温度検知ではより厳しい条件が求められますが、前を向く顔であれば、より正確に温度を計測できます
thresholdConfig.roll = 20;
thresholdConfig.yaw = 20;
thresholdConfig.verifyAreaRect = new RectF(125, 400, 565, 835); // SensePassデバイスを例にとります       
IdentifyManager.getInstance().setThresholdConfig(thresholdConfig);

温度検知機能には、温度検知モジュール(サーマルイメージングシステム)が必要です。TemperatureCameraFactoryクラスを介して対応するサーマルイメージングシステムオブジェクトを取得することで初期化できます。サーマルイメージングシステムの初期化には数秒かかりますのでご注意ください。

// カメラタイプを取得します
CameraType type = TemperatureCameraUtils.getCameraType();
// サーマルイメージングシステムオブジェクトを作成します
ITemperatureCamera mTemperatureCamera = TemperatureCameraFactory.getTemperatureCamera(type);
// 初期化します
mTemperatureCamera.initCamera(this);

温度データの取得後、温度検知アルゴリズムによって温度値を調整する必要があります。アルゴリズムは次の手順で手動で初期化する必要があります。

// 温度比較アルゴリズムを初期化します(温度の調整用)
TemperConvertCallback temperConvertCallback = new TemperConvertCallback(){

            private float[] tempArray;

            @Override
            public float temperConvertCentigrade(float temper){

                return TemperatureCameraFactory.getTemperatureCamera(type).getCentigradeFromTemperatureData(temper);
            }

            @Override
            public float[] getTempMatrix(float[] y16Frame, int y16W, int y16H, float distance, int x, int y, int w, int h){

                int size = w * h;
                if(tempArray == null || tempArray.length != size){
                    tempArray = new float[size];
                }
                TemperatureCameraFactory.getTemperatureCamera(type).matrixTemperature(y16Frame, y16W, y16H, distance, x, y, w, h,                                         temperConvertCallback = tempArray);
                return tempArray;
            }
        };
// ご注意: デバイスによってアルゴリズムのバージョンが異なります。
// 現在SenseThunderEがサポートするのは TempMeasureVersion.TempMeasure_1_2_0、TempMeasureVersion.TempMeasure_1_5_0、TempMeasureVersion.TempMeasure_1_6_0、TempMeasureVersion.TempMeasure_1_7_0 とする
// SenseThunderAirがサポートするのは TempMeasureVersion.TempMeasure_1_7_0、TempMeasureVersion.TempMeasure_1_8_0 とする
// SenseThunderE-miniがサポートするのは TempMeasureVersion.TempMeasure_1_5_0、TempMeasureVersion.TempMeasure_1_11_0、TempMeasureVersion.TempMeasure_1_10_0、TempMeasureVersion.TempMeasure_1_3_0 とする
// 詳しくは、TemperatureMeasureVersionUtils.getTempMeasureVersionByDevice()での実行をご参照ください。
TempMeasureVersion algorithmVersion = TemperatureMeasureVersionUtils.getTempMeasureVersionByDevice();
int ret = TemperatureActionProxy.init(algorithmVersio, temperConvertCallbackn);
if(ret == 0){
        Log.d(TAG, "Temperature Measurement Algorithm Initialized Successfully");
}

Identity Manager に Temperature Sdk Action を設定します。

ITemperatureSdkAction action = new ITemperatureSdkAction(){

            @Override
            public <T extends TrackAndTemperatureResult> List<T> temperCalculateAir(MatchFace[] matchFaces, @Nullable Bitmap temperatureBitmap, float[] temperatureData, int temperatureWidth, int temperatureHeight, FaceOrientation temperatureOrientation){
                // 使用している機器の周囲の温度
                // CameraType が CameraType.GUIDE120 または CameraType.IRAY の場合のコード例は次のとおりです
                   MatchFace matchFace = matchFaces[0];
                    float envTemperature = 25.1f;
                    TemperInfo temperInfo = TemperatureActionProxy.temperCalculateObtainRect(matchFace.rgbFace, temperatureData,
                                                                                     temperatureWidth, temperatureHeight, FaceOrientation.UP.getValue(), envTemperature, 0.1f);
                    TrackAndTemperatureResult trackAndTemperatureResult = new TrackAndTemperatureResult();
                    trackAndTemperatureResult.setFaceInfo(matchFace.rgbFace);
                    trackAndTemperatureResult.setIrFaceInfo(matchFace.irFace);
                    trackAndTemperatureResult.setTemperature(temperInfo.temper);

                    List<T> ts = new ArrayList<>();
                    ts.add((T)trackAndTemperatureResult);
                    return ts;
            }
        };
            }
        };
// Temperature Sdk Action を設定します
IdentifyManager.getInstance().setTemperatureSdkAction(action);

サーモカメラプレビューデータを取得します(熱力学線図)。温度データを取得したら、間に合うようにIdentify Managerに挿入する必要があります。

ITemperaturePreviewDataCallback mPreviewDataCallback =
          new ITemperaturePreviewDataCallback(){

          @Override
      public void onTemperaturePreviewData(
            Bitmap temperatureBitmap, float[] temperatureValue, int width, int height){

                // temperatureBitmap - 温度ビットマッププレビューの描画に使用できる熱力学線図
                // temperatureValue - 温度データ
                // 幅、高さ - 熱力学線図の熱の幅および高さ

                // Identify Manager に温度データを挿入します(温度検知機能を有効化後に温度データが挿入されない場合、認証は実行されません)
                IdentifyManager.getInstance().handleTemperatureData(
                  temperatureBitmap, temperatureValue,width, height, mCameraUseConfig.faceOrientation);
            }
        };

// コールバックを設定します
mTemperatureCamera.addTemperaturePreviewDataCallback(mPreviewDataCallback);

認証コールバック結果から、個人の体温データを取得します。

//認証結果コールバックインターフェースを介して、顔認証結果を取得します
IIdentifyResultCallback identifyCallback = new IIdentifyResultCallback(){

    @Override
    public void onDrawFaces(@Nullable List<FaceInfo> list){
        // 顔検知コールバック。顔設定フレームの描画に使用できます。
        // 認証が一時停止されてもこのコールバックは発生することに注意する必要があります。その場合、プロセス内で顔はトラッキングされているものの、認識されていない状態となります。
    }

    @Override
    public void onClearScreen(){
        // スクリーンを消去するコールバック。カメラの視野に顔が入っていない場合、本コールバックでスクリーンを消去します。
    }

    @Override
    public void onUnknown(float faceW){
                // 顔が大きすぎたり、小さすぎたりして、生体であるかどうか判断できない場合は、本メソッドで通知されます
    }

    @Override
    public void onIdentifyResult(List<FrameIdentifyResult> frameIdentifyResults){
                //認証結果のコールバック
              for(int i = 0; i < frameIdentifyResults.size(); i++){
            FrameIdentifyResult frameIdentifyResult = frameIdentifyResults.get(i);
            if(frameIdentifyResult == null
                    || frameIdentifyResult.faceIdentifyResults == null
                    || frameIdentifyResult.faceIdentifyResults.size()<= 0){
                continue;
            }
            List<FaceIdentifyResult> faceIdentifyResults = frameIdentifyResult.faceIdentifyResults;
            for(int j = 0; j < faceIdentifyResults.size(); j++){
                FaceIdentifyResult faceIdentifyResult = faceIdentifyResults.get(j);
                if(faceIdentifyResult == null || faceIdentifyResult.getIdentifyResultTypeEnum()== null){
                    continue;
                }
                TrackAndTemperatureResult trackAndTemperatureResult = faceIdentifyResult.getTrackAndTemperatureResult();
                float temperature = 0;
                if(trackAndTemperatureResult != null){
                    temperature = trackAndTemperatureResult.getTemperature();
                }
                Log.i(TAG, String.format(Locale.getDefault(), "userId-%d temperature is %f",
                                         faceIdentifyResult.getUserId(), temperature));
            }
        }
    }
};

// 結果を設定するコールバック
IdentifyManager.getInstance().setIdentifyCallback(identifyCallback);

Passアクセスコントロールの使用

Passアクセスコントロール機能を使用するには、グローバル初期化設定が必要です。初期化手順は次のとおりです。

// Passアクセスコントロール機能を使用する前に、本機能の初期化を呼び出す必要があります
DoorDeviceAccessProxy.init();

final DoorAccessConfig config = new DoorAccessConfig.Builder()
        // GPIO の B ポートの入力タイプを設定します。デフォルトでは GPIO_IN_NONE に設定されます。
        .setGpioInB(DoorAccessConfig.GPIO_IN_NONE)
        // GPIO の C ポートの入力タイプを設定します。デフォルトでは GPIO_IN_NONE に設定されます。
        .setGpioInC(DoorAccessConfig.GPIO_IN_NONE)
        // ドアオープン時間を設定します。ローカルリレーのみ(ここでは、開いた後、5 秒で閉じるように設定しています)。
        .setOpenDoorTime(5)
        // GPIO 出力タイプを設定します
        .setGpioOutA(DoorAccessConfig.GPIO_OUT_NONE)
        // RS485 データの読み書きをファームウェアで制御します(ファームウェアに対応している必要があります。対応していない場合は、false に設定してください)
        .setIsSupportRS485GpioAutoControl(true)
        // Wiegand 入力プロトコルタイプを設定します
        .setWiegandInput(DoorAccessConfig.WIEGAND26_24_BIT)
        // ドアオープンモードを設定します
        .setOpenDoorMode(DoorAccessConfig.OPEN_DOOR_MODE_RELAY)
        .Setthe Serial Port Baud Rate for RS485 Protocol
        .setRS485BaudRate(9600)
        .build();
DoorDeviceAccessProxy.setConfig(config);

Passアクセスコントロール機能を使用するための設定は、DoorDeviceAccessProxy.setConfig(config)で変更できます。

Passアクセスコントロール機能の主要なカテゴリ:

  • DoorDeviceAccessProxy:グローバルな初期化、リソースの解放、設定の使用、ドアのオープンコントロールなどを行います。

  • DoorAccessConfig:ドアアクセス設定のカテゴリです。

  • PassDoorDeviceAccessProxy:ドアチャイム、RS485 プロトコル、アラート、盗難アラートライトなど、PassやThunderシリーズデバイスで利用可能なアクセスコントロール機能を管理します。

ローカルリレー経由のドアオープン

「ローカルリレー」は、独自のアクセサリが付属したハードウェアデバイスで、ドアのオープンコントロールやドアオープン時間の設定に使用されます(ドアを開いて数秒後に閉じるなど)。本機能をサポートするハードウェアモデルは、PassとThunderシリーズです。

Passアクセスコントロール機能の使い方は次のとおりです。

// オープンドアモードを「ローカルリレー」に設定します
DoorAccessConfig mDoorAccessConfig = DoorDeviceAccessProxy.getConfig();
mDoorAccessConfig.setOpenDoorMode(DoorAccessConfig.OPEN_DOOR_MODE_RELAY);
DoorDeviceAccessProxy.setConfig(mDoorAccessConfig);

// 本メソッドはグローバルなドアオープンメソッドで、設定された方法に応じて自動的にドアオープン操作を実行します
// IC カード番号は入力パラメーターがWiegand Open Doorの場合のみ使用します。ここに直接転送します。
DoorDeviceAccessProxy.openDoor("");

DoorDeviceAccessProxy.openDoor()は、設定されたドアオープンの方法とクローズを遅延させる時間を自動的に取得し、自動的にドアオープン操作を実行します。利用者は具体的なオープン方法を気にする必要はなく、メソッドによって自動的に制御されます。次に示すネットワークリレーやWiegandコントローラーによるドアオープンの場合も同様です。

特にクローズ遅延時間を30秒を超えて設定する必要がある場合、次の方法でドアを開く必要があります。

// opDoorTime で設定した時間が経過したらドアを閉めます。遅延時間は次の方法で直接決まります
DoorDeviceAccessProxy.openDoorWithRelay(openDoorTime *1000);

ローカルリレーをすぐに閉じる必要がある場合、手動で次のメソッドを呼び出せます。

DoorDeviceAccessProxy.closeRelayDoor();

ネットワークリレー経由のドアオープン

「ネットワークリレー」は周辺機器です。ハードウェアデバイスはネットワークを介してネットワークリレーに接続し、ネットワークリレーにドアのオープンコマンドを送信することでドアオープン時間やクローズ遅延時間を制御します。本機能に対応するハードウェアモデルは、PassとThunderシリーズです。

Passアクセスコントロール機能は、次のように使用します。

DoorAccessConfig mDoorAccessConfig = DoorDeviceAccessProxy.getConfig();
// IP 番号を入力するだけです。デフォルトでポートは12345 に設定されています。初期化時に設定されている場合は、ここでは繰り返し設定不要です。
mDoorAccessConfig.setRelayIp("192.168.12.11");
// オープンドアモードをネットワークリレーに設定します
mDoorAccessConfig.setOpenDoorMode(DoorAccessConfig.OPEN_DOOR_MODE_IP_RELAY);
DoorDeviceAccessProxy.setConfig(mDoorAccessConfig);

// パラメーターは、クローズ遅延時間です。自由に設定できます。
DoorDeviceAccessProxy.openDoor("");

Wiegand コントローラー経由のドアオープン

「Wiegand コントローラー」は拡張インターフェースを介してハードウェアデバイスに接続し、データ通信にWiegandプロトコルを使用する周辺機器です。ドアオープンを制御することができます。SDKでは現在、Wiegand 26、Wiegand 32、およびWiegand 34に対応しています。本機能に対応するハードウェアモデルはPassとThunderシリーズです。

標準的なWiegand 26プロトコルでサポートされている最大カード番号は8ビットで、カード番号のデータ転送はHIDとPIDに分かれています。HIDとPIDの生成モードに応じて、Wiegand 26は、「Wiegand 26(24 ビット)」および「Wiegand 26(8および16ビット)」の2種類のモードに分かれます。相違点は次のとおりです。

  • Wiegand 26(24 ビット): 通常使用するモードで、カード番号は int に変換され、2^16で割って整数にしたものがHIDになり、2^16の余りがPIDとなります。

  • Wiegand 26(8 および16 ビット): 特別に使用するモードで、カード番号の最初の3桁がHIDとしてintに変換され、最後の5桁がPIDとしてintに変換されます。

Passアクセスコントロール機能の使い方は次のとおりです。

  • Wiegand 26経由のドアオープン

String cardNumver = "12345678";
// Wiegand 26(24 ビット)経由でドアを開きます
DoorDeviceAccessProxy.openDoor(cardNumber);
  • Wiegand 32 または 34 経由のドアオープン

String cardNumver = "1234567890";
DoorDeviceAccessProxy.openDoor(cardNumber);

Wiegand カード読み取り

「Wiegand カード読み取り」は、周辺機器であるWiegandリーダーを使用して設定する必要があります。拡張インターフェースを介してデバイスと接続し、データ通信にWiegandプロトコルを使用してICカードの番号を読み取ります。Wiegand 26、Wiegand 32、およびWiegand 34に対応しています。本機能に対応するハードウェアデバイスのモデルは、PassとThunderシリーズです。

Passアクセスコントロール機能の使い方は次のとおりです。

DoorAccessConfig config = DoorDeviceAccessProxy.getConfig();
// Wiegand 26標準カードリーダーを設定します
config.setWiegandInput(DoorAccessConfig.WIEGAND26_24_BIT);
DoorDeviceAccessProxy.setConfig(config);

設定の完了後、Wiegand読み取りコールバックをlistenすることができます。コードの使い方は次のとおりです。

DoorDeviceAccessProxy.setCardReaderCallback(
            new WiegandReaderDevice.CardReaderCallback(){

    @Override
    public void onRead(String cardNumber){
        // カード番号の読み取りに成功しました。cardNumberがカード番号です。
    }
});

GPIO入力デバイス

「GPIO 入力デバイス」は、GPIOポートを介して接続されたハードウェアデバイスにGPIO信号を送信するデバイスの一種であり、ドアオープンボタン、消防アラートシグナル、ドアマグネットなどが含まれます。使用時には、ハードウェアデバイスが受信側、GPIO入力デバイスが送信側となり、GPIO入力ポートを介して通信します。本機能に対応するハードウェアデバイスのモデルは、PassとThunderシリーズです。

Passアクセスコントロール機能は、BポートとCポートに分かれたデュアルGPIOに対応しています。使用前に関連するアクセスコントロールの設定を次のように行います。

DoorAccessConfig mDoorAccessConfig = DoorDeviceAccessProxy.getConfig();
// ここでは、周辺機器がBポートを介して、ドアボタンに接続されていると仮定します。Cポートを使用する場合は、doorAccessConfig.setGpioInC()を設定してください。
mDoorAccessConfig.setGpioInB(DoorAccessConfig.GPIO_IN_DOOR_BUTTON);
DoorDeviceAccessProxy.setConfig(mDoorAccessConfig);

設定の完了後、関連する信号入力をlistenすることができます。コードの使い方は次のとおりです。

// ドアボタンを使用する場合
PassDoorDeviceAccessProxy.setOnClickDoorButtonListener(
                new DoorButtonDevice.DoorButtonOnClickListener(){

        @Override
        public void onClick(){
            // ドアオープン信号を受け取ります
        }
});

// 消防アラートシグナル受信リスナーを使用する場合
PassDoorDeviceAccessProxy.setReceiveFireSignListener(
                new FireSignalDevice.ReceiveFireSignListener(){

        @Override
        public void onReceive(){
            // 消防アラートシグナルを受け取ります
        }
});

// ドアセンサーを使用する場合
PassDoorDeviceAccessProxy.setDoorStateCallback(
                new PassDoorDeviceAccessProxy.DoorMagnetismStateCallback(){

        @Override
        public void onDoorStateChanged(int state){
            if(state == '0'){
                // ドアの磁器ステータス: オフ
            } else {
                // ドアの磁器ステータス: オン
            }
        }
});

GPIO出力デバイス

「GPIO出力デバイス」は、ドアベルやアラートなどのハードウェアデバイスからGPIO信号を受信するために、GPIO出力ポートを介して接続された周辺機器を指します。使用時には、ハードウェアデバイスが送信側、GPIO出力デバイスが受信側となり、両者はGPIO出力ポートを介して通信します。本機能に対応するハードウェアデバイスのモデルは、PassとThunderシリーズです。

使用前に、関連するアクセスコントロールの設定を次のように行います。

DoorAccessConfig sgDoorAccessConfig = DoorDeviceAccessProxy.getConfig();
// ここでは、ドアベルを使用していると仮定しています
sgDoorAccessConfig.setGpioOutA(DoorAccessConfig.GPIO_OUT_DOOR_BELL);
DoorDeviceAccessProxy.setConfig(sgDoorAccessConfig);

// ドアベルを鳴らす場合のパラメーターは時間です(ドアベルのメーカーは鳴動時間を指定するのではなく、回数を指定して鳴らすように設定している場合があるため、実際の鳴動時間には誤差が生じる可能性があります)
PassDoorDeviceAccessProxy.pressDoorBell(2000);

アラートの使用時には、具体的に手動でアラートを制御したり、オフにしたりする必要があります。コードの使い方は次のとおりです。

// アラートが鳴ります
PassDoorDeviceAccessProxy.pressAlarmBell();
// 手動でアラートをオフにします
PassDoorDeviceAccessProxy.releaseAlarmBell();

照明コントロール

「照明コントロール」とはRGBフィルライト、IRフィルライト、スクリーンバックライトなど、主にハードウェアデバイスの照明アクセサリを制御します。

IRフィルライト

「IRフィルライト」はIRカメラモジュールの一部で、IR画像を向上させるために使用されます。フィルライトの耐用年数を延ばすために、使用していないときは電源を切るように動的に制御できます。本機能に対応するハードウェアデバイスのモデルは、PassとThunderシリーズです。

コードの使い方は次のとおりです。

// IRフィルライトをオンにします
PassDoorDeviceAccessProxy.turnOnIrLight();

// IRフィルライトをオフにします
PassDoorDeviceAccessProxy.turnOffIrLight();

スクリーンバックライト

「スクリーンバックライト」はハードウェアデバイスに付属するアクセサリで、ソフトウェアアプリケーションが休止状態(ソフトウェアアプリケーションが使われていない深夜帯など)のときにスクリーンライトを消すことで、ハードウェア機器の耐用年数を延ばし、エネルギー消費を抑えることができます。本機能に対応するハードウェアデバイスのモデルは、PassとThunderシリーズです。

コードの使い方は次のとおりです。

// スクリーンバックライトをオフにします
PassDoorDeviceAccessProxy.closeBackLight();

// スクリーンバックライトをオンにします
PassDoorDeviceAccessProxy.openBackLight();

RS485 プロトコル

「RS485 プロトコル」とはシリアル通信のプロトコル規格です。RS485インターフェースは、半二重モードでの通信に対応するためにハードウェアデバイスに用意されています。半二重データの読み取り専用および書き込み専用はファームウェアによって自動的に制御されるため、上位ビジネス層ではシリアル通信にのみ注意するだけで済みます。本機能に対応するハードウェアデバイスのモデルは、PassとThunderシリーズです。

使用前にまずRS485をオンにしてから、ユースケースに応じてボーレート、データバッファ、およびデータトランシーバーのタイムアウト時間を設定します。コードの使い方は次のとおりです。

// RS485を開始し、ボーレートを9600、読み取りバッファーサイズを32、タイムアウト時間を3秒にそれぞれ設定します
PassDoorDeviceAccessProxy..enableRS485(9600, 32,
            new RS485Device.RS485ReceiveListener(){

            @Override
            public void onReceive(byte[] data, long dataLength){
                // 受信データ
            }

        }, 3000, new SerialPortReader.OnReadTimeOutListener(){

            @Override
            public void onTimeout(byte[] data, long dataLength){
                // データ読み取りタイムアウト
            }
        }
});

データを送信するには、次のコードを使用します。

PassDoorDeviceAccessProxy.sendDataByRS485(data);

盗難アラートボタン

「盗難アラートボタン」はハードウェアデバイスに付属しているアクセサリで、デバイスの背面に持ち上げ型ボタンで配置されています。通常動作時にボタンを押すと、ハードウェアデバイスが取り外されたときにボタンがポップアップします。ハードウェアデバイスが不正に取り外された場合は、ファームウェアレベルで感知して、警告のために 「盗難アラート」を発します。

ファームウェアレベルでは「盗難アラートボタン」をF2キー入力イベントに変換します。すなわち「盗難アラート」が鳴るとシステム層はF2キー入力イベントを送信します。F2キーの入力イベントであるため、F2キーが押されたかどうかをlistenすれば、「盗難アラートボタン」をlistenすることができます。コードの使い方は次のとおりです。

// onKeyUp()イベントを介してアクティビティでリッスンします
public class ForceDisassemblyDemoActivity extends AppCompatActivity {

    // 冗長コードは省略します

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event){
        if(keyCode == KeyEvent.KEYCODE_F2){
            // 盗難アラートをlistenします
        }
        return super.onKeyUp(keyCode, event);
    }
}

センサー

「センサー」とは照明センサーや距離センサーなど、ハードウェアデバイスに付属するセンサーを指します。通過シナリオの場合、センサーの役割は次のとおりです。

  • 照明センサー:光の強度を感知し、光量の少ない環境ではアプリケーション用に 「フィルライトモード」を設定できます。

  • 距離センサー:人の接近を感知し、特定の動作を引き起こします(例えば、人が近づくと休眠状態のデバイスを起動します)。

センサーは次のように、AndroidネイティブSDKのSensorManagerクラスで利用できます。

SensorManager mSensorManager =(SensorManager)getSystemService(Context.SENSOR_SERVICE);
// 照明センサーを使用します。距離センターを使用するには、Sensor.TYPE_PROXIMITY パラメーターを使用します。
Sensor lightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
if(lightSensor != null){

    mSensorManager.registerListener(new SensorEventListener(){
        @Override
        public void onSensorChanged(SensorEvent event){
            // event.value[0]を介して特定の値を取得し、特定の処理を実行します
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy){

        }
    }, lightSensor, SensorManager.SENSOR_DELAY_NORMAL);

} else {
     // センサーを使用できません
}

ブザー

「ブザー」はハードウェアデバイスに付属するアクセサリで、主にハードウェアデバイスでアラートが発生したときにビープ音を鳴らすために使用されます。現在、SensePass、SenseThunderE-miniデバイスのみがこの機能をサポートしています。ブザーを使用するには、次に示すコードでオンとオフを手動で制御する必要があります。

// ブザーをオンにします
PassDoorDeviceAccessProxy.pressBuzzer();

// ブザーをオフにします
PassDoorDeviceAccessProxy.releaseBuzzer();

アプリケーションシステム署名

SDKのサンプルプロジェクトには、システム署名ファイルsensetime.jksが配置されています。このファイルをアプリケーション署名として使用すると、プリケーションがシステム権限を取得でき、システムイベントの設定やシステム設定の変更などの高いレベルの権限を必要とする操作を実行できるようになります。

使用するにはプロジェクト内のメインモジュールのルートにsensetime.jksをコピーしてから、次の設定をbuild.gradleファイルに追加します。

android {

    signingConfigs {
        system {
            keyAlias 'sensetime'
            keyPassword 'sensetime'
            storeFile file('./sensetime.jks')
            storePassword 'sensetime'
        }
    }

    buildTypes {
        debug {
            signingConfig signingConfigs.system
            // ...
        }
        release {
            signingConfig signingConfigs.system
            // ...
        }
    }
}

また、次のようにシステムアプリケーション宣言android:sharedUserId="android.uid.system"をAndroidManifest.xmlファイルに追加します。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="thunder.wksample"
    android:sharedUserId="android.uid.system">
</manifest>

QRコード認証

QRコード認証機能は、通常のQRコードを認識することができる機能です。使用する際にはエンコードおよびデコードライブラリとしてZXingまたはZBarを選択できます。エンドツーサイドでのデバイス認証に適していて、より高速なZBarの使用を推奨します。使用方法については,サンプルコードをご覧ください。簡単な使い方は次のとおりです。

QRCodeDecoderProxy qRCodeDecoder = new QRCodeDecoderProxy(new ZBarDecoderImpl());
// previewData は、カメラのプレビューフレームデータです
qRCodeDecoder.decodeQRCode(previewData,1280, 720);

最終更新