解決Android指紋識別Crash異常java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.hardware.fingerprint.FingerprintManager.isHardwareDetected()' on a null object的問題及原因探究
問題
應用需要提交至小米應用市場,未審核通過,下圖是小米審核的結果
小米給的log比較完整,整個log文件都有28M多,下載后先直接搜索關鍵字beginning of crash或FATAL EXCEPTION: main,找到異常信息如下:
--------- beginning of crash
07-3100:25:17.6841010863186318 E AndroidRuntime: FATAL EXCEPTION: main
07-3100:25:17.6841010863186318 E AndroidRuntime: Process: com.ktt.xxx, PID:631807-3100:25:17.6841010863186318 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ktt.xxx/com.ktt.smarthome.activity.MainActivityWithSlide}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.hardware.fingerprint.FingerprintManager.isHardwareDetected()' on a null object reference
07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2841)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2919)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.ActivityThread.-wrap11(Unknown Source:0)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1637)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.os.Looper.loop(Looper.java:176)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6656)07-3100:25:17.6841010863186318 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)07-3100:25:17.6841010863186318 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)07-3100:25:17.6841010863186318 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)07-3100:25:17.6841010863186318 E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.hardware.fingerprint.FingerprintManager.isHardwareDetected()' on a null object reference
07-3100:25:17.6841010863186318 E AndroidRuntime: at com.ktt.smarthome.activity.MenuFram.isFingerPrintAvailable(MenuFram.java:105)07-3100:25:17.6841010863186318 E AndroidRuntime: at com.ktt.smarthome.activity.MenuFram.onActivityCreated(MenuFram.java:74)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.Fragment.performActivityCreated(Fragment.java:2517)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1562)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1623)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManager.java:3032)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2984)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.FragmentController.dispatchActivityCreated(FragmentController.java:178)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:7080)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:7065)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)07-3100:25:17.6841010863186318 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2794)07-3100:25:17.6841010863186318 E AndroidRuntime:...9 more
通過上面發現,具體crash異常如下: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.hardware.fingerprint.FingerprintManager.isHardwareDetected()' on a null object 通過異常信息NullPointerException,可以很容易看出這是個空指針異常,要解決這個問題到是很簡單,定位到異常所在的文件,所在的行。異常的代碼如下:
再之后,在 Android 9.0(Android P Api 28),Google 對生物識別進行了進一步增強,開放了以 BiometricPrompt 為核心的新 Api,存在于 androidx.biometric 包和android.hardware.biometrics包下,Google 在開發者文檔中是這樣解釋的:
On devices running P and above, this will show a system-provided authentication prompt, using a device’s supported biometric (fingerprint, iris, face, etc).
大意是,在 Android P 及以上版本的系統中,BiometricPrompt 將展現一個由系統提供的驗證提示,用于支持設備提供的生物識別,包括指紋、虹膜、面部等。
目前來看,虹膜和面部等生物識別 Api 尚未開放,僅支持指紋識別,不過在指紋識別上進行了統一,比如要求使用統一的指紋識別 UI ,不允許開發者自定義了。