1. 程式人生 > >React Native呼叫Android原生程式碼實現車牌識別功能【附效果圖附原始碼】

React Native呼叫Android原生程式碼實現車牌識別功能【附效果圖附原始碼】

        這段時間研究了下React Native,Facebook推出的,結合了Web應用和Native應用的優勢,可以使用JavaScript來開發iOS和Android原生應用,決定簡單研究下,於是開始搭建環境,編寫HelloWorld,完成後又覺得HelloWorld過於簡單(執行完命令你就擁有一個HelloWorld了),根本沒有領會到RN在專案中的應用,剛好前段時間研究了車牌識別,所以決定把RN和車牌識別功能整合到一起折騰下,更深入的瞭解下RN。由於之前沒有用過RN,在編寫的過程中踩了很多坑,查資料的時候才發現原來好多人都踩過,如果你匯入原始碼後不能直接執行,我只能告訴你這是正常的:)

注:本文主要專注於原始碼的大概介紹,講的不是很詳細,需要大家閱讀原始碼體會,文末會給出原始碼地址,如果你想先體驗一下效果,可以下載apk安裝試試,文末也會給出下載地址。

這個demo也是站在巨人的肩膀上完成的,在此感謝以下網站/原始碼的作者,感謝他們的無私奉獻和開源精神:

        目前關於RN的資料已經有很多了,作者主要是在該網站上學習RN的,講的很詳細

基於openCV的中文車牌識別系統,執行在Windows系統上,詳細介紹可以檢視專案的Readme

基於EasyPR移植的Android版本,本demo車牌識別部分就是基於該原始碼進行開發的,對拍照部分重新進行了開發,優化了照片的解析度以及自動對焦功能,增加了車牌識別度。

4.其他相關資料的作者,有很多關於RN踩坑的:)  

準備工作:

      需要搭建好Android開發環境,準備好AS開發工具(Git環境可選)

    需要搭建好NDK開發環境

    需要搭建好RN開發環境

    然後就可以開幹了

作者的主要開發環境如下:
System:              Ubuntu14.04   
Android Studio:     V2.3.1
Gradle:                  V2.14.1
NDK:                     android-ndk-r14b

(一)老規矩,先看下效果圖(本來準備做動圖的,原諒我太懶--!):

1.圖片車牌號識別


2.真實車牌號識別,車牌號最後一位打碼,你懂的(等紅燈的時候也不忘測試,有沒有很感動^ ^)


(二)原始碼目錄簡介

1.RN原始碼目錄結構


由檔案的時間可知demo其實是在四月份就編寫的,為什麼現在才發出來?原諒我太任性:)

如果你研究過RN的HelloWorld,對這個目錄應該就沒有疑問了,這是RN原始碼的根目錄,通過react-native的init命令直接初始化來的(正常應該還有ios資料夾,我移除了)

2.Android原生程式碼目錄結構


展開RN目錄中android資料夾,這是原生程式碼的根目錄,Android Studio結構的,也就意味著接下來是使用AS來開發原生原始碼

OpencvNative目錄裡存放著OpenCV相關的原始碼,該原始碼是在EasyPR_Android的jni部分引入的,EasyPR_Android都已經配置好了,你只需要有ndk編譯環境就可以擁有


(三)匯入方法簡介

對原始碼的開發工作分兩部分:

是RN部分,這部分原始碼不需要匯入AS,直接編輯後執行即可,作者使用vscode進行編輯。

是Android原生程式碼部分,這部分原始碼可以匯入AS後進行編輯和編譯,方法同正常的AS專案。

匯入成功後你看到的介面是這個樣子的:


注:匯入後需要修改ndk路徑,在app/build.gradle裡,把下面程式碼中兩處紅色字型部分的ndk路徑修改為自己的路徑:

task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
    commandLine "/home/lucher/main/softs/ndk/android-ndk-r14b/ndk-build",
            '-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
'-j', Runtime.runtime.availableProcessors(),
            'all',
            'NDK_DEBUG=0'
}

task cleanNative(type: Exec, description: 'Clean JNI object files') {
    commandLine "/home/lucher/main/softs/ndk/android-ndk-r14b/ndk-build",
            '-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
'clean'
}

(四)執行方法

完成了原始碼的匯入工作後,就可以執行看看效果了,可以使用AS編譯apk的方法打出apk後安裝執行,也可以通過AS的執行功能直接執行,還可以通過RN提供的方法執行,在此列舉如下兩種方法:

方法一,通過AS執行:

下面所說的命令可以使用系統的Terminal執行,也可以使用AS的Terminal執行

1.如果是在真機上除錯需要執行如下命令:

$ adb reverse tcp:8081 tcp:8081

否則執行後頁面可能會出現:Could not get BatchedBridge,make sure your bundle is packaged correctly的錯誤

2.啟動RN服務,執行如下命令(如果使用系統Terminal需要先cd到RN原始碼的根目錄):

$ npm start

執行完這兩個命令後就可以使用AS的Run命令來執行程式了,成功啟動服務的結果如下:


方法二,通過RN執行:

該方法不依賴AS,使用系統Terminal執行,執行命令之前,需要先cd到RN原始碼根目錄

1.啟動RN相關服務

$ react-native start 

(react-native start和npm start都可以開啟服務,具體有啥區別還沒搞明白,有了解的還望賜教)

2.執行程式

$ react-native run-android

如果順利,這時候程式就啟動了,成功啟動結果如下:


(五)那些年踩過的坑

在編寫React Native的時候,遇到了各種各樣的問題,當時記錄了一些問題,可檢視原始碼下readme.md中問題記錄部分

由於對RN不是很瞭解,demo中某些實現方法不是很合理(例如獲取掃描結果部分),如果要在實際專案中使用,有些地方還需優化,文中或原始碼中如果有錯誤還望指出。

原始碼較大,已上傳至本人github:

想先體驗效果的可以下載apk檔案: