Androidで生体認証(指紋・顔認証)を実装するには BiometricPrompt APIを使う。
依存を追加する
app/build.gradle に依存を追加する。
dependencies {
implementation "androidx.biometric:biometric:1.1.0"
}
androidx.biometric ライブラリはマニフェストマージにより USE_BIOMETRIC パーミッションを自動的に追加するため、手動での追加は不要だ。意図を明示したい場合は AndroidManifest.xml に明示的に記述する。
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
生体認証が利用可能か確認する
BiometricManager を使って端末が生体認証に対応しているか確認する。
val biometricManager = BiometricManager.from(this)
when (biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG)) {
BiometricManager.BIOMETRIC_SUCCESS -> {
// 生体認証が利用可能
}
BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE -> {
// 生体認証ハードウェアなし
}
BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE -> {
// ハードウェアが現在利用不可
}
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> {
// 生体情報が未登録
}
}
canAuthenticate の引数には認証の強度を指定する。
| 定数 | 説明 |
|---|---|
BIOMETRIC_STRONG | Class 3 の強い生体認証(主に指紋認証) |
BIOMETRIC_WEAK | Class 2 の弱い生体認証(多くのデバイスの顔認証) |
DEVICE_CREDENTIAL | PIN・パターン・パスワード |
BiometricPrompt を実装する
認証コールバックを作成する
認証結果を受け取るコールバックを作成する。
val authenticationCallback = object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
// 認証成功時の処理
}
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
super.onAuthenticationError(errorCode, errString)
// 認証エラー時の処理
}
override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
// 認証失敗時の処理(認識できなかった場合など)
}
}
onAuthenticationFailed は生体情報が登録済みの情報と一致しなかった場合に呼ばれる。認証をキャンセルした場合や試行の上限回数を超えた場合は onAuthenticationError が呼ばれる。
BiometricPrompt を作成する
FragmentActivity または Fragment から BiometricPrompt を作成する。
val biometricPrompt = BiometricPrompt(
this, // FragmentActivity または Fragment
ContextCompat.getMainExecutor(this),
authenticationCallback
)
ダイアログの情報を設定する
PromptInfo で認証ダイアログに表示する情報を設定する。
val promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle("生体認証")
.setSubtitle("アプリにログインするために認証してください")
.setNegativeButtonText("キャンセル")
.setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG)
.build()
setNegativeButtonText はキャンセルボタンのテキストを指定する。DEVICE_CREDENTIAL を setAllowedAuthenticators に含める場合は setNegativeButtonText を設定できない。
認証を開始する
biometricPrompt.authenticate(promptInfo)
実際のアプリではボタンのクリックなど、ユーザーの操作をトリガーにして認証を開始する。
val button = findViewById<Button>(R.id.button)
button.setOnClickListener {
biometricPrompt.authenticate(promptInfo)
}
まとめ
全体のコードをまとめると以下になる。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val biometricManager = BiometricManager.from(this)
if (biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG)
!= BiometricManager.BIOMETRIC_SUCCESS) {
// 生体認証が利用不可
return
}
val authenticationCallback = object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
// 認証成功時の処理
}
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
super.onAuthenticationError(errorCode, errString)
// 認証エラー時の処理
}
override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
// 認証失敗時の処理
}
}
val biometricPrompt = BiometricPrompt(
this,
ContextCompat.getMainExecutor(this),
authenticationCallback
)
val promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle("生体認証")
.setSubtitle("アプリにログインするために認証してください")
.setNegativeButtonText("キャンセル")
.setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG)
.build()
val button = findViewById<Button>(R.id.button)
button.setOnClickListener {
biometricPrompt.authenticate(promptInfo)
}
}
}
参考
\確かな知識を身に着けたい、Androidアプリ開発を学びたい人にオススメ!/
