Table of Contents
Flutter で iOS や Android の端末に搭載されている生体認証(指紋)を使ってロックを解除できるアプリを作る方法についてです。
生体認証を導入するには、パッケージ flutter_lock_screen が便利です。
指紋認証のためのパッケージをインストール
flutter_lock_screen は、パッケージ local_auth に依存しているため、これも同時にインストールします。
プロジェクトの pubspec.yaml に以下の dependencies に以下のように記載します。
dependencies: local_auth: ^0.6.3+4 flutter_lock_screen: ^1.0.8 ...
(バージョン番号は将来変わる可能性があります)
サンプルコードと画像リソース
インストールが完了したら、これらを利用する Dart のソースファイルに忘れずにインポートします。
import 'package:local_auth/local_auth.dart'; import 'package:flutter_lock_screen/flutter_lock_screen.dart';
実際に指紋やパスコードによるロック解除を行うクラスの例を以下に記載します。ほとんどflutter_lock_screenのサンプルと同じものですが、一部変更しています。
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:local_auth/local_auth.dart'; import 'package:flutter_lock_screen/flutter_lock_screen.dart'; class PassCodeScreen extends StatefulWidget { PassCodeScreen({Key key}) : super(key: key); @override _PassCodeScreenState createState() => _PassCodeScreenState(); } class _PassCodeScreenState extends State<PassCodeScreen> { bool isFingerprint = false; Future<Null> biometrics() async { final LocalAuthentication auth = LocalAuthentication(); bool authenticated = false; try { authenticated = await auth.authenticateWithBiometrics( localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: false); } on PlatformException catch (e) { print(e); } if (!mounted) return; if (authenticated) { setState(() { isFingerprint = true; }); } } @override Widget build(BuildContext context) { var myPass = [1, 2, 3, 4]; return LockScreen( title: "パスワードを入力", passLength: myPass.length, bgImage: "images/bg.jpg", fingerPrintImage: "images/fingerprint.png", showFingerPass: true, fingerFunction: biometrics, fingerVerify: isFingerprint, borderColor: Colors.white, showWrongPassDialog: true, wrongPassContent: "再度入力してください", wrongPassTitle: "失敗", wrongPassCancelButtonText: "Cancel", passCodeVerify: (passcode) async { for (int i = 0; i < myPass.length; i++) { if (passcode[i] != myPass[i]) { return false; } } return true; }, onSuccess: () { Navigator.of(context).pushReplacement( MaterialPageRoute(builder: (BuildContext context) { return [認証後に開くWidgetを指定]; })); }); } }
プロジェクトにフォルダ images を作成し、使用する画像(bg.jpg、fingerprint.png)を入れます。画像ファイルはこちらからダウンロードするか、自分で用意したものを使用してください。
画像を読み込むためには pubspec.yaml の assets にもファイルパスを書き込みます。
assets: - images/bg.jpg - images/fingerprint.png # または、ディレクトリごと # - images/
OSごとの処理
iOS の場合、顔認証を使用する際には Info.plist に以下を記載します。
<key>NSFaceIDUsageDescription</key> <string>FaceIDを使用する理由をここに書く</string>
Android の場合、AndroidManifest.xml の manifest タグ内に生体認証を使うためのパーミッションを記載します。
ドキュメントでは USE_FINGERPRINT を記載するよう指示されていましたが API level 28 以降は非推奨なので USE_BIOMETRIC を使用します。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.app"> ... <uses-permission android:name="android.permission.USE_BIOMETRIC"/> <!-- 非推奨 <uses-permission android:name="android.permission.USE_FINGERPRINT"/> --> </manifest>
そして、MainActivity.kt において FlutterActivity から FlutterFragmentActivity を使用するように変更します。
package パッケージ名 import androidx.annotation.NonNull; import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugins.GeneratedPluginRegistrant class MainActivity: FlutterFragmentActivity() { override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine); } }
エディタ上では赤線で警告が表示されるかもしれませんが、無視して構いません。
これを行わないと以下のエラーが実行時に発生します。
PlatformException(no_fragment_activity, local_auth plugin requires activity to be a FragmentActivity., null, null)
また、上記の設定後に以下のようなエラーが出ることがあります。
Unhandled Exception: MissingPluginException(No implementation found for method authenticateWithBiometrics on channel plugins.flutter.io/local_auth)
この場合、以下の三つを試してみてください。
- “Android Studio”の再起動
- “flutter clean”のコマンド
- スマホにインストールしたテストアプリの完全削除
動作例
以上で設定が完了しました。実際に動かしてみると、パスコード入力画面が開きます。
左側にある指紋のマークをタップすると、指紋認証の画面が開きます。
(スクリーンショットの撮影はシステムで禁止されていました)
ロックを解除すると、指定したウィジェットが立ち上がります。
以上、指紋認証でロックを解除できるアプリの作成方法でした。