Help us understand the problem. What is going on with this article?

Androidで指紋認証を軽く利用してみる

More than 3 years have passed since last update.

セールでNexus 6Pをゲットしたので指紋認証APIを使ってみました。
Android 6.0端末にハードウェアの指紋認証センサーがあり、指紋登録が済んでいる場合に動作するように書いています。

FingerprintManagerで提供されている機能

FingerprintManagerというのが、Androidでの指紋認証を提供しています。
FingerprintManager#authenticate時に指紋センサーに触れた指紋が、予め端末に登録してある指紋の中に存在するかを確認することができます。

Permission

指紋認証を利用するには、予めパーミッションを宣言しておかないといけないのでAndroidManifest.xmlに追記しておきましょう。

<uses-permission android:name="android.permission.USE_FINGERPRINT"/>

下準備

アプリケーションが本当に、パーミッションを持っているのか確認しないとAndroidStudioに怒られるようになったので、FingerprintManagerを使う前に確認を行います

if (checkSelfPermission(Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
    return;
}

認証してみる

FingerprintManagerの取得

FingerprintManagerが指紋の認証機能を提供します。getSystemService(Context.FINGERPRINT_SERVICE)で取得できます。

FingerprintManager fingerprintManager = (FingerprintManager) getSystemService(Context.FINGERPRINT_SERVICE);

指紋認証可能か調べる

認証に入る前に、端末が指紋認証を利用できるのかどうかを確認しないといけません
FingerprintManager#isHardwareDetected()で指紋センサーが端末に存在するのか
FingerprintManager#hasEnrolledFingerprints()で指紋が登録されているのかを取得することができます。
どちらかがtrueならば利用できると考えて良いでしょう。

if (fingerprintManager.isHardwareDetected() || fingerprintManager.hasEnrolledFingerprints()) {
    // 認証可能
}

認証

実際に認証を行うために、FingerprintManager#authenticateメソッドを呼びます。
呼ぶと、ユーザー指紋センサーに触れるまで待機状態になります。(画面上にはなにも表示されないので、実際はダイアログ等を予め表示しておかないとわからないです)

fingerprintManager.authenticate(null, null, 0, new FingerprintManager.AuthenticationCallback() {
    @Override
    public void onAuthenticationError(int errorCode, CharSequence errString) {
        Toast.makeText(MainActivity.this, "onAuthenticationError: " + errString, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
        Toast.makeText(MainActivity.this, "onAuthenticationHelp: " + helpString, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
        Toast.makeText(MainActivity.this, "onAuthenticationSucceeded", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onAuthenticationFailed() {
        Toast.makeText(MainActivity.this, "onAuthenticationFailed", Toast.LENGTH_SHORT).show();
    }
}, new Handler());

引数など詳細はこちらにありますが、ざっくり言うと

authenticate (FingerprintManager.CryptoObject crypto, CancellationSignal cancel, int flags, FingerprintManager.AuthenticationCallback callback, Handler handler)
  • crypto
    指紋認証成功時に利用する鍵を設定します。使わない場合はnull。これを使うと指紋認証でログインができるようになるようです。

  • cancel
    指紋認証を途中でキャンセルするためのオブジェクトを設定します。ここに指定したCancellationSignalインスタンスのcancelメソッドを呼ぶことで、指紋認証を途中でキャンセルすることができます。使わない場合はnull

  • flags
    0を設定する

  • callback
    成功時や、失敗時などのコールバック

  • handler
    コールバックを呼ぶHandler

コールバック

FingerprintManager.AuthenticationCallbackには4つのコールバックがあります。呼ばれるタイミングは以下です。

  • onAuthenticationError(int errorCode, CharSequence errString)
    エラー時に呼ばれます。キャンセル時もここが呼ばれます。

  • onAuthenticationHelp(int helpCode, CharSequence helpString)
    読み取り不十分だった場合などに呼ばれます。helpStringの中に原因の文章が入ります。このメソッドが呼ばれても指紋認証自体は終了していないので再度指紋センサーに触れるとハンドリングされます。

  • onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result)
    指紋認証に成功したときに呼ばれます。resultの中には、authenticateの時に指定したcryptoが入っています。

  • onAuthenticationFailed()
    登録されていない指紋が検出された時はこちらが呼ばれます。このメソッドが呼ばれても指紋認証自体は終了していないので再度指紋センサーに触れるとハンドリングされます。

サンプル

実際に使うには AlertDialog等で、指紋認証中であることを表す必要があります。ダイアログのキャンセル時にCancellationSignal#cancelを呼んでおくと、指紋認証をキャンセルすることができます。
ダイアログを消すタイミングは、指紋認証が終了するonAuthenticationError, onAuthenticationSucceededが良さそうです。

public class MainActivity extends AppCompatActivity {

    private Dialog mDialog;
    private CancellationSignal mCancellationSignal;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button) findViewById(R.id.button);
        button.setText("端末に登録されている指紋で認証を行う");
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                useFingerprint();
            }
        });
    }

    private void useFingerprint() {
        if (checkSelfPermission(Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
            return;
        }

        FingerprintManager fingerprintManager = (FingerprintManager) getSystemService(Context.FINGERPRINT_SERVICE);
        if (fingerprintManager.isHardwareDetected() || fingerprintManager.hasEnrolledFingerprints()) {

            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("指紋認証");
            builder.setMessage("指紋センサーに触れてください");
            builder.setNegativeButton("キャンセル", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    mCancellationSignal.cancel();
                }
            });
            builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    mCancellationSignal.cancel();
                }
            });
            mDialog = builder.show();

            mCancellationSignal = new CancellationSignal();

            fingerprintManager.authenticate(null, mCancellationSignal, 0, new FingerprintManager.AuthenticationCallback() {
                @Override
                public void onAuthenticationError(int errorCode, CharSequence errString) {
                    Toast.makeText(MainActivity.this, "onAuthenticationError: " + errString, Toast.LENGTH_SHORT).show();
                    mDialog.dismiss();
                }

                @Override
                public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
                    Toast.makeText(MainActivity.this, "onAuthenticationHelp: " + helpString, Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
                    Toast.makeText(MainActivity.this, "onAuthenticationSucceeded", Toast.LENGTH_SHORT).show();
                    mDialog.dismiss();
                }

                @Override
                public void onAuthenticationFailed() {
                    Toast.makeText(MainActivity.this, "onAuthenticationFailed", Toast.LENGTH_SHORT).show();
                }
            }, new Handler());
        }
    }
}

akkuma
Androidアプリ書いてます。得意技はCanvas。
http://akkuma.info
mixi
全ての人に心地よいつながりを
http://mixi.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away