AndroidXにおけるBiometricPromptAPIについて

Android

Posted on Oct 25


今回の主題

私自身、もともとFingerprintManagerを使用し指紋認証を実装していて、Android PよりBiometricPromptに乗り換えましたがそこで1つの問題が発生しました。
その問題を強引に(スマートではなく)解決し運用をしていましたが、AndroidXのBiometricPromptを使ってみたところ、問題が解決されており、更に使い方も変わっていました。
使い方に関しての変更も探した限りでは解説などが見つからなかったので備忘録を兼ねて書かせていただきたいと思います。

BiometricPromptとは

Android端末における生体認証はAndroid P以前ではFingerprintManagerを使用して指紋認証を行なうことで実現していました。
そのFingerpringManagerはAndroid PよりDeprecatedになり新しく登場したのがBiometricPromptです。
2018年6月21日にはAndroid Developers BlogにAndroid Developers Blog: Better Biometrics in Android Pという記事も投稿されました。
これに従ってFingerprintManagerからBiometricPromptへ乗り換えることによって、もっと生体認証を使いやすく、また指紋以外での認証も可能になるというものでした。

AndroidX以前のBiometricPrompt

BiometricPrompt  |  Android Developers
パッケージとしてはandroid.hardware.biometricsに存在するものでした。
使い方も前述したDevelopers Blogに乗っている通り

1
2
3
4
5
6
7
BiometricPrompt.Builder(this)
    .setTitle("title")
    .setSubtitle("sub title")
    .setDescription("description")
    .setNegativeButton("cancel", executor, listener)
    .build()
    .authenticate(cryptoObject, cancellationSignal, executor, callback)

という記述で生体認証のダイアログを表示し、認証を行うことができました(引数に取るクラスについての詳細はAndroid Developersをごらんください。)

ここで問題になってくるのはBiometricPrompt自体はAndroid P以上で触るものであって、Android O以下ではManagerを触る必要があります。
つまり、VERSION.SDK_INT >= Build.VERSION_CODES.PでBiometricPromptを使うか、FingerprintManagerを使うかを場合分けしなければいけないということです。
そこでその差異を吸収するのがCompatLibraryになってきます(Androidアプリ開発者であればCompatは慣れ親しんだものだと思います。)

前述のAndroid Developers Blogの表を引用させていただくと

という表があります。
この表から分かる通りアプリケーションからはSupport Libraryである、BiometricPrompt Compat Libraryを触って、そこがよしなにバージョンに寄ってしてくれると信じていました。

信じていました、が、BiometricPrompt Compat Libraryはどこにも見つからずどこだどこだと彷徨っていました。

他にもそういう方が居た。

中国人のfythonさんが出しているライブラリでfython/BiometricPromptCompat: [DEPRECATED] A Thrid-party BiometricPrompt compat library.というものがあり、実装を見るといい感じに中でバージョン分けをするみたいな「求めていたBiometricPrompt Compat Library!」がありました。

このような感じで、BiometricPromptが出てきたのは良いが、Compatがないので結局今までのFingerprintManagerに追加してP以上であればBiometricPrompt、未満ならというコード量が増える形になっていました。

AndroidXでのBiometricPrompt

上記OSSの個人ライブラリのREADMEでも既に[DEPRECATED]とありますが、AndroidXになってBiometricPromptが大きく変わり上記の問題も解決されていました。
Maven Repository: androidx.biometric » biometricまだバージョンは1.0.0のalpha02が現時点では最新です。

BiometricPrompt  |  Android Developers

このAndroid Developersのドキュメントを見ても分かる通り、BiometricPromptに直接Builderが存在しなくなったりと以前の書き方のままでは動かない形に変更されていました。
まず表示させる完成形のコードをそのまま貼り付けます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
val promptInfo = BiometricPrompt.PromptInfo.Builder()
    .setTitle("title")
    .setSubtitle("sub title")
    .setDescription("description")
    .setNegativeButtonText("cancel")
    .build()

BiometricPrompt(this, mainExecutor, object : BiometricPrompt.AuthenticationCallback() {
    override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
        // 認証成功時のハンドル
    }    

    override fun onAuthenticationFailed() {
        // 認証失敗時のハンドル
    }

    override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
        // 認証エラー時のハンドル
    }
}).authenticate(promptInfo)

(そのままActivityクラスに貼り付けると動くと思います)

変更点としては、タイトルなどの情報をコレまでは直接BiometricPromptのBuilderに対してsetTitleなどを行ってきましたが、AndroidXからはそれらの情報類はBiometricPrompt.PromptInfoというクラスができたので、そちらにまとめてインスタンスを作る形になっているようです。

まとめ

androidx.biometrics.BiometricPromptの実装をちょっと覗いてみましたが、まさにif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { ... } else { ... }という形でバージョンの場合分けでどれを使うかという実装になっていました。
最初に僕たちが求めていたBiometricPrompt Compat LibraryのそれがやっとAndroidXになって登場したという感じだと思います。

ただ、まだAndroidXに移行しきっていないケースが多いことやAndroidXのBiometricがアルファ版であることから、まだしばらくはFingerprintManagerと以前のBiometricPromptを自分たちで場合分けしてるケースが続くのかなと思います。
AndroidXに移行しきっている場合だと入れてみても良さそうです。


このエントリーをはてなブックマークに追加
comments powered by Disqus

<< 2018年まとめ     キャッシュレス生活2018 in 京都 >>



2018やぎ小屋