1. 程式人生 > >Android 6.0 指紋識別功能學習(一)----阿冬專欄!!!

Android 6.0 指紋識別功能學習(一)----阿冬專欄!!!


轉載自:http://www.cnblogs.com/changyuet/p/5535082.html


    由於畢設需要設計增強的身份認證(生物特徵認證方式),所以需要學習指紋識別相關的android6.0功能,進而設計自己的畢設:支援媒體可信通訊的android ims終端設計。

學習之前也不幸遇到坑爹的事情,本來為了做這個畢設,需要廉價採購一個支援指紋識別的android手機,最後選擇了紅米note3 雙網通版,剛開始買的時候正好遇到google釋出支援指紋識別的android6.0新系統,心想:買了這個支援android5.0的指紋識別手機,回來刷機一下,升級到android6.0,然後進行指紋識別相關的功能開發,結果,等了快一年了,小米公司都沒有釋出支援android6.0的紅米note3雙網通版的刷機包,多方查詢資料才得知:由於紅米note3雙網通版採用的聯發科的MTK Helio X10處理器而不是高通的處理器,真他麼坑啊:




更可氣的是最近新推出的紅米note3全網通版竟然採用了高通驍龍650處理器,原因不用多說,鑑於高通的能力,果不其然,馬上這個全網通版就支援了android6.0.。這讓我們這些買了紅米note3雙網通版的其何以堪,尤其是我這個做開發的,忍不住想罵人,,,,,,,,,

唉,坑爹的小米,怪不得最近市值由原來的400億美元驟降到當前的40億美元估值,活該。


廢話不多說了,蒐集了一個不錯的關於android6.0支援指紋識別功能詳解的文章,看了看,講得不錯,就收藏下來了:


轉載自:http://www.cnblogs.com/changyuet/p/5535082.html


引言

https://mobile100.gitbooks.io/Android/content/paper/2015/1501210538.html

最近小米公司新出了一款手機紅米note3十分受到大家的青睞,一方面原因可能是因為它比較廉價,但我認為最吸引眼球的是它是一款帶有指紋識別的手機。2015年下半年出的手機基本都帶有指紋識別功能,不管是炒得很熱的360奇酷手機、魅族手機,還是“中華酷聯”旗下的手機都開始加入指紋識別的功能,指紋識別似乎已經成標配,購買手機時考慮是否帶有指紋識別功能似乎也成為了消費者的一個購物傾向。

指紋識別為何受到人們的青睞?答案似乎很明顯,因為它比較方便,而且安全性也要比簡單的數字密碼要安全的多,但我想對於廣大手機使用者來說,如果能夠通過手指按壓直接解鎖手機是要比解鎖輸入密碼方便很多的。由於很多的原因吧,指紋識別越來越受到人們的重視。

Android 5.0對於ROM的優化是毋庸置疑的,令人詬病的Dalvik被替換為ART,作業系統的整體的感覺清爽了很多。但是Android 5.0並沒有在操作內加入指紋識別的相關的支援,現在市面上Android 5.0手機的指紋識別都是一些基於Android的解決方案,並沒有在系統深層次進行處理,這也是Android慢了iOS一些的地方,但今年Google在Android的釋出會上提出Android 6.0在其系統上添加了指紋識別的相關支援,這對於廣大的Android粉絲來說真的算是一個很大的禮物。下面我對指紋識別以及Android 6.0系統中指紋識別的新特性進行分析。

指紋識別是什麼?

提到指紋識別我們就要先弄清楚什麼事指紋,指紋為何能夠做到區別性。

指紋,由於其具有終身不變性、唯一性和方便性,已幾乎成為生物特徵識別的代名詞。指紋是指人的手指末端正面面板上凸凹不平產生的紋線。紋線有規律的排列形成不同的紋型。紋線的起點、終點、結合點和分叉點,稱為指紋的細節特徵點(minutiae)。

指紋識別即指通過比較不同指紋的細節特徵點來進行鑑別。指紋識別技術涉及影象處理、模式識別、計算機視覺、數學形態學、小波分析等眾多學科。由於每個人的指紋不同,就是同一人的十指之間,指紋也有明顯區別,因此指紋可用於身份鑑定。由於每次捺印的方位不完全一樣,著力點不同會帶來不同程度的變形,又存在大量模糊指紋,如何正確提取特徵和實現正確匹配,是指紋識別技術的關鍵。

指紋識別的易用性

指紋識別功能提高了系統的易用性,不僅是解鎖螢幕,它還可以用來設定一些快捷操作如:拍照、快捷開啟程式等等,同時鑑於指紋識別的高區別性質,指紋識別不僅僅是對於功能的簡化,更深層次的是安全級別的一個提高。

~~

指紋掃描認證功能在數款安卓智慧手機上出現過,但相關模組與解決方案都來自第三方廠商,而非安卓核心或系統層面直接支援的產物。谷歌顯然看到了相關技術的發展趨勢,因此,6.0提供了來自谷歌的官方指紋API。順帶一提,蘋果也為自己的TouchID指紋讀取模組提供了類似的API。

指紋識別的安全性

隨著時代的發展網路支付等安全問題面臨越來越多的問題,這傳統的基於密碼、加密演算法和驗證碼的安全機制在安全性和方便性方面已經無法滿足現有需求,甚至已經受到挑戰。為了能夠更好地確保系統的安全性和方便性,迫切需要尋找其他的技術。於是人們將目光轉移到了生物特徵識別技術上,因為人體某些生物特徵各不相同並且不會發生變化以及很難遺失和仿製。目前被使用的生物識別技術主要有指紋、虹膜、視網膜、語音、面部、DNA以及簽名,它們各自的效能以及優缺點如表所示:

每個人的指紋獨一無二並且很難發生變化,此外,它不需要像密碼那樣需要記憶,真正做到了隨時隨地使用。目前已經有很多品種的低成本的指紋採集感測器供選擇。指紋在採集的過程中對硬體系統的要求不高,指紋採集裝置實現比較容易。目前已經有標準的指紋庫供開發者使用,識別系統開發相對比較容易,實用性強。隨著現代電子整合製造技術的提高,可以製造體積較小並且精度更高的指紋影象感測器。另外,快速可靠的指紋影象處理、識別演算法也得到迅速發展,同時現代計算機運算速度越來越快,已經完全具備在微機上進行兩個指紋的快速比對運算。可以說,目前指紋技術已經是非常成熟的生物識別技術,具有很大可靠性和實用性。

綜上所述,當前指紋識別技術因其低成本識別率高而具有最為廣闊的應用前景,已經達到實用化、產業化的程度。也正是因為指紋識別有如此多的好處,Google在2015年Android6.0釋出會上指出Android6.0會在系統級別支持指紋識別功能,雖然相對Apple晚了一些但是對於廣大的Android使用者來說這是一個福音。

指紋識別功能實現簡介

指紋識別通過指紋感測器採集資訊,進行指紋影象的預處理,然後進行特徵點提取,最後進行特徵匹配如下圖所示:

通過指紋影象感測器採集到指紋影象經常會受到感測器本身誤差、手指壓力不同以及手指存在塵埃等眾多因素影響,使得采集到的指紋影象的質量不夠高。因此首先需要對指紋影象進行預處理,以便獲得較為清晰的指紋影象併為後期的匹配做好準備工作。經過預處理後的指紋紋線被處理成單一象素點,接下來就可以對指紋影象進行特徵提取以及特徵裝配。最後將獲得的特徵資訊與指紋特徵資料庫中的指紋特徵模板做一一對比,如果有匹配的指紋模板則提取出與之一一對映的身份資訊,這樣就可以進行身份論證。

分析

1.Android程式硬體訪問機制簡介:

在 Android 系統中,最上層的面向介面的應用程式使用 Java 語言編寫,Java 編寫的應用程式都執行在 Android 特有的虛擬機器中。Android 系統是基於 Linux 核心構建,Linux 裝置驅動程式程式使用 C 語言編寫,且執行在 Linux 核心空間。使用者空間訪問硬體的方法是通過基於C庫的系統呼叫來呼叫工作於核心空間的裝置驅動程式,從而訪問到硬體。顯然使用 Java 語言開發的應用程式顯然無法直接訪問硬體。為了解決這個問題,在Android 系統中提供了硬體抽象層(HAL)來解決這個問題,硬體抽象層執行在使用者空間並且使用 C/C++語言編寫,它向下遮蔽了硬體驅動模組的實現細節,向上提供了硬體訪問服務。

2.Android系統HAL層定義分析

Android 系統為 HAL 層中的模組介面定義了規範,所有工作於 HAL的模組必須按照這個規範來編寫模組介面,否則將無法正常訪問硬體。

(1)硬體模組

Android 系統為 HAL 層中使用 struct hw_module_t結構來描述硬體模組,其定義如下:

typedef struct hw_module_t {
    uint32_t tag;
    uint16_t module_api_version;
    #define version_major module_api_version
    uint16_t hal_api_version;
    #define version_minor hal_api_version
    const char *id;
    const char *name;
    const char *author;
    struct hw_module_methods_t* methods;
    void* dso;
    uint32_t reserved[32-7];
}hw_module_t;

在 struct hwdevice_t 結構中,成員 tag 必須初始化為 HARDWARE DEVICE_TAG;成員version 為 hw_device_t 的版本號;成員 method 指向指向硬體模組描述結構體的指標;成員close 為關閉裝置的方法。

在編寫硬體抽象層模組時,必須為抽象層模組自定義一個硬體抽象層描述結構,並且必須是 struct hw_module_t 型別的變數作為它的第一個成員變數,否則該抽象層模組將無法正常工作。另外,在模組中使用自定義一個硬體抽象層描述結構定義一個變數時,它的名字必須為 HAL_MODULE_INFO_SYM(匯出符號),它會在模組被載入時用到,否則該抽象層模組會因無法正在載入而無法正常工作。

(2)硬體裝置

在硬體抽象層中使用 struct hw_device_t 結構來描述硬體裝置,其定義如下:

typedef struct hw_device_t {
    uint32_t tag;
    uint32_t version;
    struct hw_module_t* module;
    uint32_t reserved[12];
    int (*close)(struct hw_device_t* device);
} hw_device_t;  

在 struct hwdevice_t 結構中,成員 tag 必須初始化為 HARDWARE DEVICE_TAG;成員version 為 hw_device_t 的版本號;成員 method 指向指向硬體模組描述結構體的指標;成員close 為關閉裝置的方法。 在編寫硬體抽象層模組時,必須為模組所操作的硬體裝置自定義一個硬體裝置描述結 構,並且必須是 struct hw_device_t 型別的變數作為該硬體裝置描述結構的第一個成員變數,否則該抽象層模組將無法正常工作。

(3)硬體抽象層模組的操作方法

在硬體抽象層中使用 struct hw_module_methods_t 結構描述一個硬體抽象層模組的操 作方法列表,其定義如下:

typedef struct hw_module_methods_t {
    Int (*open)(const struct hw_module_t* module, const char* id,
    struct hw_device_t** device);
} hw_module_methods_t;

struct hw_module_methods_t 結構中的 open 函式指標通常被賦值為硬體模組初始化函式,在該函式中通常需要為自定義硬體裝置描述結構體分配記憶體,然後初始化其成員並且開啟硬體裝置,最後將自定義一個硬體裝置描述結構的一個成員(struct hw_device_t 型別)儲存到引數 device 中。否則該抽象層模組將無法正常工作。 以上是對於Android系統HAL層的詳細分析。

下面對Android6.0原始碼分析:

下面對比較特列的程式碼進行分析。因為程式碼量比較大,我將需要列示的程式碼列舉在附錄中供參看。

首先需要進行原始碼的下載和獲取,從官方網站下載了Android 6.0的原始碼。

獲取的程式碼需要在Linux系統下用cat 命令解壓縮 。 進行合併後目錄結構如下圖:

其下面的指紋識別相關的目錄結構:

可以看到不管是從系統核心級別還是硬體支援等方面Android 6.0 都對指紋識別添加了支援

目錄:mydroid\system\core

Fingerprintd\

Android.mk 檔案為Makefile檔案

其內容如下

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS := -Wall -Wextra -Werror -Wunused
LOCAL_SRC_FILES := \
    FingerprintDaemonProxy.cpp \
    IFingerprintDaemon.cpp \
    IFingerprintDaemonCallback.cpp \
    fingerprintd.cpp
LOCAL_MODULE := fingerprintd
LOCAL_SHARED_LIBRARIES := \
    libbinder \
    liblog \
    libhardware \
    libutils \
    libkeystore_binder
include $(BUILD_EXECUTABLE)

主要是對於這個功能的編譯時一系列的規則來指定,哪些檔案需要先編譯,哪些檔案需要後編譯等。

fingerprintd.cpp

系統中的指紋識別執行緒

#define LOG_TAG "fingerprintd"
#include <cutils/log.h>
#include <utils/Log.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/PermissionCache.h>
#include <utils/String16.h>

#include <keystore/IKeystoreService.h>
#include <keystore/keystore.h> // for error codes

#include <hardware/hardware.h>
#include <hardware/fingerprint.h>
#include <hardware/hw_auth_token.h>

#include "FingerprintDaemonProxy.h"

int main() {
    ALOGI("Starting " LOG_TAG);
    android::sp<android::IServiceManager> serviceManager = android::defaultServiceManager();
    android::sp<android::FingerprintDaemonProxy> proxy =
            android::FingerprintDaemonProxy::getInstance();
    android::status_t ret = serviceManager->addService(
            android::FingerprintDaemonProxy::descriptor, proxy);
    if (ret != android::OK) {
        ALOGE("Couldn't register " LOG_TAG " binder service!");
        return -1;
    }

    android::IPCThreadState::self()->joinThreadPool();
    ALOGI("Done");
    return 0;
}

以上列舉了兩個Android6.0中系統核心中的程式碼,Android6.0把指紋識別當做一個單獨的執行緒進行運作。可以預見這會對現在Android系統指紋識別的效率有一個質的飛躍。

H:\mydroid\frameworks\base\services\core\java\com\android\server\fingerprint

FingerprintService.java

多客戶端時硬體抽象層(HAL)對於指紋識別的支援

解決了現階段出現的多個客戶端情況下指紋識別無法使用或者出現錯誤或者卡頓的情況,因為在6.0之前使用多為第三方的解決方案,而6.0將完全支援。

以上為FingerprintService.java部分程式碼。

總結與展望

首先進行總結。本文首先介紹指紋識別技術的相關內容及其現狀,可以看出未來指紋識別是不可或缺的一種功能,不管是Android 還是其他的系統,而且通過對比得出指紋識別是現階段最安全而且最經濟易用並且在技術上有一定成熟度,無論從成熟度還是實用性方面都明顯優於其他生物識別技術。然後對於指紋識別進行了簡單的介紹,並且對指紋識別的實現方法進行了介紹。接著對Android實現系統支援指紋識別的方法進行論述,首先介紹了Android的硬體訪問機制,然後接著介紹Android HAL層在指紋識別中扮演的角色,並且介紹了其相關的函式定義和介面的規範。通過上面的準備工作,接下來我通過下載Android原始碼,進行解壓合併,分析其目錄結構,可以充分看出Android6.0在指紋識別上的支援。並且通過代表性的幾個原始碼分析Android對於指紋識別的實現方法。以上是我做的主要工作。

指紋識別的展望。指紋識別越來越受到人們的重視,Android 6.0對指紋識別的支援是Google 2015年最大的戰略,雖然在此前他們可能不看好,但是事實證明指紋識別不僅僅只是為了解鎖手機,在安全方面,包括手機的防盜這些方面都扮演了重要的角色,相信未來,不僅僅是手機,汽車,乃至家電、傢俱對於安全方面要求上都可以通過指紋來,而且物聯網現在發展迅速,指紋識別對於使用者的安全起到了重要的作用。