├── .gitattributes ├── .gitignore ├── .idea ├── $CACHE_FILE$ ├── $PRODUCT_WORKSPACE_FILE$ ├── .gitignore ├── codeStyles │ └── codeStyleConfig.xml ├── dictionaries ├── inspectionProfiles │ └── Project_Default.xml ├── libraries │ ├── Dart_SDK.xml │ ├── Flutter_Plugins.xml │ └── Flutter_for_Android.xml ├── misc.xml ├── modules.xml ├── runConfigurations │ └── example_lib_main_dart.xml └── vcs.xml ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── android ├── .gitignore ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── libs │ └── faceplatform-release.aar ├── settings.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── example │ │ └── baidu_face_plugin │ │ └── baidu_face_plugin │ │ ├── BaiduFacePlugin.java │ │ ├── CameraUtils.java │ │ ├── Config.java │ │ ├── DefaultDialog.java │ │ ├── FaceDetectActivity.java │ │ ├── FaceDetectExpActivity.java │ │ ├── FaceDetectRoundView.java │ │ ├── FaceLivenessActivity.java │ │ ├── FaceLivenessExpActivity.java │ │ ├── FaceSDKResSettings.java │ │ └── VolumeUtils.java │ ├── jniLibs │ ├── arm64-v8a │ │ ├── libFaceSDK.so │ │ └── libbaidu_license.so │ ├── armeabi-v7a │ │ ├── libFaceSDK.so │ │ └── libbaidu_license.so │ └── x86 │ │ ├── libFaceSDK.so │ │ └── libbaidu_license.so │ └── res │ ├── drawable │ ├── bg_tips.xml │ └── bg_tips_no.xml │ ├── layout │ ├── activity_face_detect.xml │ ├── activity_face_detect_v3100.xml │ ├── activity_face_liveness.xml │ ├── activity_face_liveness_v3100.xml │ └── widget_face_dialog.xml │ ├── mipmap-xhdpi │ ├── bg_face_round.png │ ├── ic_close.png │ ├── ic_disable_sound.png │ └── ic_enable_sound.png │ ├── mipmap-xxhdpi │ ├── ic_close_ext.png │ ├── ic_disable_sound_ext.png │ ├── ic_enable_sound_ext.png │ ├── ic_success.png │ └── ic_warning.png │ ├── raw │ ├── detect_face_in.mp3 │ ├── face_good.mp3 │ ├── liveness_eye.mp3 │ ├── liveness_head_down.mp3 │ ├── liveness_head_left.mp3 │ ├── liveness_head_left_right.mp3 │ ├── liveness_head_right.mp3 │ ├── liveness_head_up.mp3 │ └── liveness_mouth.mp3 │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── baidu_face_plugin.iml ├── doc ├── license-apply.png ├── license-config.png └── license-demo.png ├── example ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ ├── debug │ │ │ ├── app-debug.apk │ │ │ └── output.json │ │ ├── profile │ │ │ ├── app-profile.apk │ │ │ └── output.json │ │ ├── release │ │ │ ├── app-release.apk │ │ │ └── output.json │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── assets │ │ │ │ └── idl-license.face-android │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── baidu_face_plugin │ │ │ │ │ └── baidu_face_plugin_example │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h ├── lib │ └── main.dart ├── pubspec.lock ├── pubspec.yaml └── test │ └── widget_test.dart ├── ios ├── .gitignore ├── Assets │ └── .gitkeep ├── Classes │ ├── BaiduFacePlugin.h │ ├── BaiduFacePlugin.m │ └── SwiftBaiduFacePlugin.swift └── baidu_face_plugin.podspec ├── lib └── baidu_face_plugin.dart ├── pubspec.lock └── pubspec.yaml /.gitattributes: -------------------------------------------------------------------------------- 1 | *.* linguist-language=dart 2 | 3 | # Auto detect text files and perform LF normalization 4 | * text=auto 5 | 6 | # Always perform LF normalization on these files 7 | *.dart text 8 | *.gradle text 9 | *.html text 10 | *.java text 11 | *.json text 12 | *.md text 13 | *.py text 14 | *.sh text 15 | *.txt text 16 | *.xml text 17 | *.yaml text 18 | 19 | # Make sure that these Windows files always have CRLF line endings in checkout 20 | *.bat text eol=crlf 21 | *.ps1 text eol=crlf 22 | 23 | # Never perform LF normalization on these files 24 | *.ico binary 25 | *.jar binary 26 | *.png binary 27 | *.zip binary 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | -------------------------------------------------------------------------------- /.idea/$CACHE_FILE$: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Android > Lint > Correctness 12 | 13 | 14 | Google Web Toolkit issues 15 | 16 | 17 | Gradle 18 | 19 | 20 | Kotlin 21 | 22 | 23 | Maven 24 | 25 | 26 | OSGi 27 | 28 | 29 | Probable bugsGradle 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /.idea/$PRODUCT_WORKSPACE_FILE$: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 1.8 8 | 9 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /workspace.xml -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/dictionaries: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/libraries/Dart_SDK.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/libraries/Flutter_Plugins.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/libraries/Flutter_for_Android.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/runConfigurations/example_lib_main_dart.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: e6b34c2b5c96bb95325269a29a84e83ed8909b5f 8 | channel: stable 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.2 2 | * 支持多语言 3 | 4 | ## 1.0.1 5 | * 支持 license 信息在 MainApplication 配置 6 | 7 | ## 1.0.0 8 | * 初始化 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # baidu_face_plugin 2 | 3 | 百度人脸识别和活体检测 Flutter 插件(目前版本仅支持 Android) 4 | 5 | # 使用方式 6 | ## 注册百度开发者账号 7 | 前往 [百度开发者账号](https://ai.baidu.com) 进行注册。 8 | 9 | ## 申请并配置license 10 | 1 . 登录 [控制台](https://console.bce.baidu.com/),前往 全局->人工智能->人脸识别->人脸识别 - 离线采集SDK管理 11 | ![avatar](https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/master/doc/license-apply.png) 12 | 13 | 2 . 新建授权,填入必须的信息(Android 签名方式自行 google,新建授权需要配置签名 MD5),将结果配置在实际项目,参考 /example/android/app/build.gradle 14 | ``` 15 | signingConfigs { 16 | 17 | def password = "111111" 18 | def alias = "nutella" 19 | def filePath = "/Users/yuanchongyu/nutella.jks" // 签名文件路径 20 | 21 | debug { 22 | keyAlias alias 23 | keyPassword password 24 | storeFile file(filePath) 25 | storePassword(password) 26 | } 27 | release { 28 | keyAlias alias 29 | keyPassword password 30 | storeFile file(filePath) 31 | storePassword(password) 32 | } 33 | } 34 | ``` 35 | 3 . 下载license放在实际项目中,参考 /example/android/app/src/main/assets/idl-license.face-android 36 | ![avatar](https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/master/doc/license-config.png) 37 | 38 | > 步骤 2 和 3 中的配置可以在新建完授权后,可下载示例项目进行参考 39 | > ![avatar](https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/master/doc/license-demo.png) 40 | 41 | 42 | ## 初始化和配置 43 | 1 . 在实际项目中增加入口 application class(参考 com.example.baidu_face_plugin.baidu_face_plugin_example.MainApplication),在"初始化SDK"的地方配置 License-ID 和 License-File-Name 44 | ``` 45 | // 初始化SDK 46 | FaceSDKManager.getInstance().initialize(this, "baidu-face-plugin-face-android", "idl-license.face-android"); 47 | ``` 48 | 49 | 2 . 修改实际项目 AndroidManifest.xml 的入口 application class(参考 example - AndroidManifest.xml ) 50 | ``` 51 | result 包含两个属性(sucess和image) 75 | > success 属性表示是否完成并成功。如果 success == 'true',则 image 返回最佳人脸照片(base64格式) 76 | 77 | 78 | ## 一些说明 79 | 关于入口 application class 80 | > 入口 application class(参考 com.example.baidu_face_plugin.baidu_face_plugin_example.MainApplication)的作用是初始化和配置插件功能(活体需要哪些动作,是否随机出现;识别的光线、模糊、角度等质量要求;是否开启语音提示等),视实际情况调整。如果你的项目中已经有入口 application class,可以合并。 81 | 82 | 关于UI样式调整 83 | > 颜色的调整可以参考并重写 plugin module res/values 中的 colors.xml,放入实际项目的 res/values。 84 | > 完全定制可以参考并重写 plugin module res/layout 中的 activity_face_detect_v3100.xml 和 activity_face_liveness_v3100.xml 两个文件,放入实际项目的 res/layout。 85 | 86 | 关于人脸识别和活体检测的结果照片 87 | > 人脸识别和活体检测 成功后将返回base64格式最佳人脸照片(人脸识别就一张照片,活体检测返回的是多个动作中最佳的一张),调试的时候需要打印完整日志(debug模式或[自行分段](https://stackoverflow.com/questions/49138971/logging-large-strings-from-flutter))才能获取完整字符串。 88 | 89 | 关于多语言支持 90 | > 支持多语言配置(语音和提示文字),加入资源文件(src/main/res)后可在入口 application class 中配置(见 FaceSDKResSettings.initResMaps(soundMap, tipsMap);)。 91 | 92 | 关于依赖关系 93 | > 官方示例项目中的依赖关系为 app->faceplatform-ui->faceplatform,集成时发现部分配置需要修改 faceplatform-ui 实现,所以将 faceplatform-ui 的源码拷贝在到了 plugin module 进行调整。 94 | 95 | ## 官方集成文档 96 | > [安卓-有动作活体版](https://ai.baidu.com/ai-doc/FACE/Mk37c1pue) 97 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.example.baidu_face_plugin.baidu_face_plugin' 2 | version '1.0' 3 | 4 | buildscript { 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:4.0.0' 12 | } 13 | } 14 | 15 | rootProject.allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | apply plugin: 'com.android.library' 23 | 24 | android { 25 | compileSdkVersion 28 26 | 27 | defaultConfig { 28 | minSdkVersion 16 29 | } 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | } 34 | 35 | dependencies { 36 | api fileTree(dir: 'libs', include: ['*.jar']) 37 | api fileTree(dir: 'libs', include: ['*.aar']) 38 | // api files('libs/facesdk.jar') 39 | } 40 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip 6 | -------------------------------------------------------------------------------- /android/libs/faceplatform-release.aar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/libs/faceplatform-release.aar -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'baidu_face_plugin' 2 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 14 | 17 | 20 | 23 | 24 | -------------------------------------------------------------------------------- /android/src/main/java/com/example/baidu_face_plugin/baidu_face_plugin/BaiduFacePlugin.java: -------------------------------------------------------------------------------- 1 | package com.example.baidu_face_plugin.baidu_face_plugin; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.util.Log; 7 | import androidx.annotation.NonNull; 8 | import io.flutter.plugin.common.MethodCall; 9 | import io.flutter.plugin.common.MethodChannel; 10 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 11 | import io.flutter.plugin.common.MethodChannel.Result; 12 | import io.flutter.plugin.common.PluginRegistry; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * BaiduFacePlugin 18 | */ 19 | public class BaiduFacePlugin implements PluginRegistry.ActivityResultListener, MethodCallHandler { 20 | 21 | private static final String CHANNEL = "com.example.baidu_face_plugin"; 22 | 23 | private static final int LIVENESS_REQUEST_CODE = 10110; 24 | 25 | private static final int DETECT_REQUEST_CODE = 10111; 26 | 27 | private Activity activity; 28 | 29 | private LivenessCallback livenessCallback; 30 | 31 | private DetectCallback detectCallback; 32 | 33 | private BaiduFacePlugin(Activity activity) { 34 | this.activity = activity; 35 | } 36 | 37 | /** 38 | * Plugin registration. 39 | */ 40 | public static void registerWith(PluginRegistry.Registrar registrar) { 41 | System.out.println("====registerWith"); 42 | Log.i("BaiduFacePlugin", "====registerWith"); 43 | final BaiduFacePlugin plugin = new BaiduFacePlugin(registrar.activity()); 44 | final MethodChannel channel = new MethodChannel(registrar.messenger(), CHANNEL); 45 | channel.setMethodCallHandler(plugin); 46 | registrar.addActivityResultListener(plugin); 47 | } 48 | 49 | 50 | @Override 51 | public void onMethodCall(@NonNull final MethodCall call, @NonNull final Result result) { 52 | if ("liveness".equals(call.method)) { 53 | livenessCallback = new LivenessCallback(result); 54 | liveness(call.hasArgument("language") ? call.argument("language") : null); 55 | } else if ("detect".equals(call.method)) { 56 | detectCallback = new DetectCallback(result); 57 | detect(call.hasArgument("language") ? call.argument("language") : null); 58 | } else { 59 | result.notImplemented(); 60 | } 61 | } 62 | 63 | @Override 64 | public boolean onActivityResult(int requestCode, int resultCode, Intent data) { 65 | Log.i("BaiduFacePlugin", 66 | "onActivityResult: requestCode=" + requestCode + ", resultCode=" + resultCode + ", data=" + data); 67 | switch (requestCode) { 68 | case LIVENESS_REQUEST_CODE: { 69 | if (livenessCallback != null && data != null) { 70 | if (data.getBooleanExtra("success", false)) { 71 | livenessCallback.sucess(data.getStringExtra("image")); 72 | } else { 73 | livenessCallback.failed(); 74 | } 75 | } 76 | break; 77 | } 78 | case DETECT_REQUEST_CODE: { 79 | if (detectCallback != null && data != null) { 80 | if (data.getBooleanExtra("success", false)) { 81 | detectCallback.sucess(data.getStringExtra("image")); 82 | } else { 83 | detectCallback.failed(); 84 | } 85 | } 86 | break; 87 | } 88 | default: 89 | } 90 | return false; 91 | } 92 | 93 | private void detect(String language) { 94 | Intent intent = new Intent(activity, FaceDetectExpActivity.class); 95 | Bundle mBundle = new Bundle(); 96 | mBundle.putString("language", (language == null || "".equals(language)) ? "zh" : language); 97 | intent.putExtras(mBundle); 98 | activity.startActivityForResult(intent, DETECT_REQUEST_CODE); 99 | } 100 | 101 | private void liveness(String language) { 102 | Intent intent = new Intent(activity, FaceLivenessExpActivity.class); 103 | Bundle mBundle = new Bundle(); 104 | mBundle.putString("language", (language == null || "".equals(language)) ? "zh" : language); 105 | intent.putExtras(mBundle); 106 | activity.startActivityForResult(intent, LIVENESS_REQUEST_CODE); 107 | } 108 | 109 | class LivenessCallback { 110 | 111 | private Result result; 112 | 113 | public LivenessCallback(Result result) { 114 | this.result = result; 115 | } 116 | 117 | public void sucess(String image) { 118 | Map map = new HashMap<>(); 119 | map.put("success", "true"); 120 | map.put("image", image); 121 | result.success(map); 122 | } 123 | 124 | public void failed() { 125 | Map map = new HashMap<>(); 126 | map.put("success", "false"); 127 | result.success(map); 128 | } 129 | 130 | } 131 | 132 | class DetectCallback { 133 | 134 | private Result result; 135 | 136 | public DetectCallback(Result result) { 137 | this.result = result; 138 | } 139 | 140 | public void sucess(String image) { 141 | Map map = new HashMap<>(); 142 | map.put("success", "true"); 143 | map.put("image", image); 144 | result.success(map); 145 | } 146 | 147 | public void failed() { 148 | Map map = new HashMap<>(); 149 | map.put("success", "false"); 150 | result.success(map); 151 | } 152 | 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /android/src/main/java/com/example/baidu_face_plugin/baidu_face_plugin/CameraUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017 Baidu Inc. All rights reserved. 3 | */ 4 | package com.example.baidu_face_plugin.baidu_face_plugin; 5 | 6 | import android.hardware.Camera; 7 | 8 | /** 9 | * CameraUtils 10 | */ 11 | public class CameraUtils { 12 | 13 | public static final String TAG = CameraUtils.class.getSimpleName(); 14 | 15 | public static void releaseCamera(Camera camera) { 16 | try { 17 | camera.release(); 18 | } catch (RuntimeException e2) { 19 | e2.printStackTrace(); 20 | } catch (Exception e1) { 21 | e1.printStackTrace(); 22 | } finally { 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /android/src/main/java/com/example/baidu_face_plugin/baidu_face_plugin/Config.java: -------------------------------------------------------------------------------- 1 | package com.example.baidu_face_plugin.baidu_face_plugin; 2 | 3 | 4 | import com.baidu.idl.face.platform.LivenessTypeEnum; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class Config { 10 | 11 | public static List livenessList = new ArrayList<>(); 12 | public static boolean isLivenessRandom = false; 13 | } -------------------------------------------------------------------------------- /android/src/main/java/com/example/baidu_face_plugin/baidu_face_plugin/DefaultDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Baidu Inc. All rights reserved. 3 | */ 4 | package com.example.baidu_face_plugin.baidu_face_plugin; 5 | 6 | import android.app.Dialog; 7 | import android.content.Context; 8 | import android.content.DialogInterface; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.view.ViewGroup.LayoutParams; 12 | import android.widget.TextView; 13 | 14 | 15 | /** 16 | * DefaultDialog 17 | * 描述:通用Dialog 18 | */ 19 | public class DefaultDialog extends Dialog { 20 | 21 | public DefaultDialog(Context context) { 22 | super(context); 23 | } 24 | 25 | public DefaultDialog(Context context, int theme) { 26 | super(context, theme); 27 | } 28 | 29 | public static class Builder { 30 | 31 | private Context context; 32 | private String title; 33 | private String message; 34 | private String negative; 35 | private OnClickListener negativeButtonClickListener; 36 | 37 | public Builder(Context context) { 38 | this.context = context; 39 | } 40 | 41 | public Builder setMessage(String message) { 42 | this.message = message; 43 | return this; 44 | } 45 | 46 | public Builder setMessage(int message) { 47 | this.message = (String) context.getText(message); 48 | return this; 49 | } 50 | 51 | public Builder setTitle(int title) { 52 | this.title = (String) context.getText(title); 53 | return this; 54 | } 55 | 56 | public Builder setTitle(String title) { 57 | this.title = title; 58 | return this; 59 | } 60 | 61 | public Builder setNegativeButton(int negativeButtonText, 62 | OnClickListener listener) { 63 | this.negative = (String) context 64 | .getText(negativeButtonText); 65 | this.negativeButtonClickListener = listener; 66 | return this; 67 | } 68 | 69 | public Builder setNegativeButton(String negativeButtonText, 70 | OnClickListener listener) { 71 | this.negative = negativeButtonText; 72 | this.negativeButtonClickListener = listener; 73 | return this; 74 | } 75 | 76 | public DefaultDialog create() { 77 | 78 | LayoutInflater inflater = (LayoutInflater) context 79 | .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 80 | 81 | final DefaultDialog dialog = new DefaultDialog(context, R.style.DefaultDialog); 82 | View layout = inflater.inflate(R.layout.widget_face_dialog, null); 83 | dialog.addContentView(layout, new LayoutParams( 84 | LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 85 | ((TextView) layout.findViewById(R.id.dialog_title)).setText(title); 86 | 87 | if (negative != null) { 88 | ((TextView) layout.findViewById(R.id.dialog_button)) 89 | .setText(negative); 90 | if (negativeButtonClickListener != null) { 91 | layout.findViewById(R.id.dialog_button) 92 | .setOnClickListener(new View.OnClickListener() { 93 | public void onClick(View v) { 94 | negativeButtonClickListener.onClick(dialog, 95 | DialogInterface.BUTTON_NEGATIVE); 96 | } 97 | }); 98 | } 99 | } else { 100 | layout.findViewById(R.id.dialog_button).setVisibility( 101 | View.GONE); 102 | } 103 | if (message != null) { 104 | ((TextView) layout.findViewById(R.id.dialog_message)).setText(message); 105 | } 106 | dialog.setContentView(layout); 107 | return dialog; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /android/src/main/java/com/example/baidu_face_plugin/baidu_face_plugin/FaceDetectActivity.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017 Baidu Inc. All rights reserved. 3 | */ 4 | package com.example.baidu_face_plugin.baidu_face_plugin; 5 | 6 | import android.app.Activity; 7 | import android.content.BroadcastReceiver; 8 | import android.content.Context; 9 | import android.graphics.Bitmap; 10 | import android.graphics.BitmapFactory; 11 | import android.graphics.PixelFormat; 12 | import android.graphics.Point; 13 | import android.graphics.Rect; 14 | import android.graphics.drawable.Drawable; 15 | import android.hardware.Camera; 16 | import android.media.AudioManager; 17 | import android.os.Bundle; 18 | import android.text.TextUtils; 19 | import android.util.DisplayMetrics; 20 | import android.util.Log; 21 | import android.view.Display; 22 | import android.view.Gravity; 23 | import android.view.Surface; 24 | import android.view.SurfaceHolder; 25 | import android.view.SurfaceView; 26 | import android.view.View; 27 | import android.view.WindowManager; 28 | import android.widget.FrameLayout; 29 | import android.widget.ImageView; 30 | import android.widget.LinearLayout; 31 | import android.widget.RelativeLayout; 32 | import android.widget.TextView; 33 | 34 | import com.baidu.aip.face.stat.Ast; 35 | import com.baidu.idl.face.platform.FaceConfig; 36 | import com.baidu.idl.face.platform.FaceSDKManager; 37 | import com.baidu.idl.face.platform.FaceStatusEnum; 38 | import com.baidu.idl.face.platform.IDetectStrategy; 39 | import com.baidu.idl.face.platform.IDetectStrategyCallback; 40 | import com.baidu.idl.face.platform.utils.APIUtils; 41 | import com.baidu.idl.face.platform.utils.Base64Utils; 42 | import com.baidu.idl.face.platform.utils.CameraPreviewUtils; 43 | 44 | import java.util.HashMap; 45 | import java.util.Map; 46 | import java.util.Set; 47 | 48 | /** 49 | * 人脸采集接口 50 | */ 51 | public class FaceDetectActivity extends Activity implements 52 | SurfaceHolder.Callback, 53 | Camera.PreviewCallback, 54 | Camera.ErrorCallback, 55 | VolumeUtils.VolumeCallback, 56 | IDetectStrategyCallback { 57 | 58 | public static final String TAG = FaceDetectActivity.class.getSimpleName(); 59 | public static final String DETECT_CONFIG = "FaceOptions"; 60 | 61 | // View 62 | protected View mRootView; 63 | protected FrameLayout mFrameLayout; 64 | protected SurfaceView mSurfaceView; 65 | protected SurfaceHolder mSurfaceHolder; 66 | protected ImageView mCloseView; 67 | protected ImageView mSoundView; 68 | protected ImageView mSuccessView; 69 | protected TextView mTipsTopView; 70 | protected TextView mTipsBottomView; 71 | protected FaceDetectRoundView mFaceDetectRoundView; 72 | protected LinearLayout mImageLayout; 73 | // 人脸信息 74 | protected FaceConfig mFaceConfig; 75 | protected IDetectStrategy mIDetectStrategy; 76 | // 显示Size 77 | private Rect mPreviewRect = new Rect(); 78 | protected int mDisplayWidth = 0; 79 | protected int mDisplayHeight = 0; 80 | protected int mSurfaceWidth = 0; 81 | protected int mSurfaceHeight = 0; 82 | protected Drawable mTipsIcon; 83 | // 状态标识 84 | protected volatile boolean mIsEnableSound = true; 85 | protected HashMap mBase64ImageMap = new HashMap(); 86 | protected boolean mIsCreateSurface = false; 87 | protected volatile boolean mIsCompletion = false; 88 | // 相机 89 | protected Camera mCamera; 90 | protected Camera.Parameters mCameraParam; 91 | protected int mCameraId; 92 | protected int mPreviewWidth; 93 | protected int mPreviewHight; 94 | protected int mPreviewDegree; 95 | // 监听系统音量广播 96 | protected BroadcastReceiver mVolumeReceiver; 97 | 98 | @Override 99 | public void onCreate(Bundle savedInstanceState) { 100 | super.onCreate(savedInstanceState); 101 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 102 | setContentView(R.layout.activity_face_detect_v3100); 103 | DisplayMetrics dm = new DisplayMetrics(); 104 | Display display = this.getWindowManager().getDefaultDisplay(); 105 | display.getMetrics(dm); 106 | mDisplayWidth = dm.widthPixels; 107 | mDisplayHeight = dm.heightPixels; 108 | 109 | String language = this.getIntent().getStringExtra("language"); 110 | language = (language == null || "".equals(language)) ? "zh" : language; 111 | FaceSDKResSettings.changeResLanguage(language); 112 | 113 | mFaceConfig = FaceSDKManager.getInstance().getFaceConfig(); 114 | 115 | AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 116 | int vol = am.getStreamVolume(AudioManager.STREAM_MUSIC); 117 | mIsEnableSound = vol > 0 ? mFaceConfig.isSound : false; 118 | 119 | mRootView = this.findViewById(R.id.detect_root_layout); 120 | mFrameLayout = (FrameLayout) mRootView.findViewById(R.id.detect_surface_layout); 121 | 122 | mSurfaceView = new SurfaceView(this); 123 | mSurfaceHolder = mSurfaceView.getHolder(); 124 | mSurfaceHolder.setSizeFromLayout(); 125 | mSurfaceHolder.addCallback(this); 126 | mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 127 | 128 | int w = mDisplayWidth; 129 | int h = mDisplayHeight; 130 | 131 | FrameLayout.LayoutParams cameraFL = new FrameLayout.LayoutParams( 132 | (int) (w * FaceDetectRoundView.SURFACE_RATIO), (int) (h * FaceDetectRoundView.SURFACE_RATIO), 133 | Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL); 134 | 135 | mSurfaceView.setLayoutParams(cameraFL); 136 | mFrameLayout.addView(mSurfaceView); 137 | 138 | mRootView.findViewById(R.id.detect_close).setOnClickListener(new View.OnClickListener() { 139 | @Override 140 | public void onClick(View v) { 141 | onBackPressed(); 142 | } 143 | }); 144 | 145 | mFaceDetectRoundView = (FaceDetectRoundView) mRootView.findViewById(R.id.detect_face_round); 146 | mCloseView = (ImageView) mRootView.findViewById(R.id.detect_close); 147 | mSoundView = (ImageView) mRootView.findViewById(R.id.detect_sound); 148 | mSoundView.setImageResource(mIsEnableSound ? 149 | R.mipmap.ic_enable_sound_ext : R.mipmap.ic_disable_sound_ext); 150 | mSoundView.setOnClickListener(new View.OnClickListener() { 151 | @Override 152 | public void onClick(View v) { 153 | mIsEnableSound = !mIsEnableSound; 154 | mSoundView.setImageResource(mIsEnableSound ? 155 | R.mipmap.ic_enable_sound_ext : R.mipmap.ic_disable_sound_ext); 156 | if (mIDetectStrategy != null) { 157 | mIDetectStrategy.setDetectStrategySoundEnable(mIsEnableSound); 158 | } 159 | } 160 | }); 161 | mTipsTopView = (TextView) mRootView.findViewById(R.id.detect_top_tips); 162 | mTipsBottomView = (TextView) mRootView.findViewById(R.id.detect_bottom_tips); 163 | mSuccessView = (ImageView) mRootView.findViewById(R.id.detect_success_image); 164 | 165 | mImageLayout = (LinearLayout) mRootView.findViewById(R.id.detect_result_image_layout); 166 | if (mBase64ImageMap != null) { 167 | mBase64ImageMap.clear(); 168 | } 169 | } 170 | 171 | @Override 172 | public void onResume() { 173 | super.onResume(); 174 | setVolumeControlStream(AudioManager.STREAM_MUSIC); 175 | mVolumeReceiver = VolumeUtils.registerVolumeReceiver(this, this); 176 | if (mTipsTopView != null) { 177 | mTipsTopView.setText(R.string.detect_face_in); 178 | } 179 | startPreview(); 180 | } 181 | 182 | @Override 183 | public void onPause() { 184 | super.onPause(); 185 | stopPreview(); 186 | } 187 | 188 | @Override 189 | public void onStop() { 190 | super.onStop(); 191 | VolumeUtils.unRegisterVolumeReceiver(this, mVolumeReceiver); 192 | mVolumeReceiver = null; 193 | if (mIDetectStrategy != null) { 194 | mIDetectStrategy.reset(); 195 | } 196 | stopPreview(); 197 | } 198 | 199 | @Override 200 | public void finish() { 201 | super.finish(); 202 | } 203 | 204 | @Override 205 | public void volumeChanged() { 206 | try { 207 | AudioManager am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE); 208 | if (am != null) { 209 | int cv = am.getStreamVolume(AudioManager.STREAM_MUSIC); 210 | mIsEnableSound = cv > 0; 211 | mSoundView.setImageResource(mIsEnableSound 212 | ? R.mipmap.ic_enable_sound_ext : R.mipmap.ic_disable_sound_ext); 213 | if (mIDetectStrategy != null) { 214 | mIDetectStrategy.setDetectStrategySoundEnable(mIsEnableSound); 215 | } 216 | } 217 | } catch (Exception ex) { 218 | ex.printStackTrace(); 219 | } 220 | } 221 | 222 | private Camera open() { 223 | Camera camera; 224 | int numCameras = Camera.getNumberOfCameras(); 225 | if (numCameras == 0) { 226 | return null; 227 | } 228 | 229 | int index = 0; 230 | while (index < numCameras) { 231 | Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); 232 | Camera.getCameraInfo(index, cameraInfo); 233 | if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 234 | break; 235 | } 236 | index++; 237 | } 238 | 239 | if (index < numCameras) { 240 | camera = Camera.open(index); 241 | mCameraId = index; 242 | } else { 243 | camera = Camera.open(0); 244 | mCameraId = 0; 245 | } 246 | return camera; 247 | } 248 | 249 | protected void startPreview() { 250 | if (mSurfaceView != null && mSurfaceView.getHolder() != null) { 251 | mSurfaceHolder = mSurfaceView.getHolder(); 252 | mSurfaceHolder.addCallback(this); 253 | } 254 | 255 | if (mCamera == null) { 256 | try { 257 | mCamera = open(); 258 | } catch (RuntimeException e) { 259 | e.printStackTrace(); 260 | } catch (Exception e) { 261 | e.printStackTrace(); 262 | } 263 | } 264 | 265 | if (mCamera == null) { 266 | return; 267 | } 268 | if (mCameraParam == null) { 269 | mCameraParam = mCamera.getParameters(); 270 | } 271 | 272 | mCameraParam.setPictureFormat(PixelFormat.JPEG); 273 | int degree = displayOrientation(this); 274 | mCamera.setDisplayOrientation(degree); 275 | // 设置后无效,camera.setDisplayOrientation方法有效 276 | mCameraParam.set("rotation", degree); 277 | mPreviewDegree = degree; 278 | if (mIDetectStrategy != null) { 279 | mIDetectStrategy.setPreviewDegree(degree); 280 | } 281 | 282 | Point point = CameraPreviewUtils.getBestPreview(mCameraParam, 283 | new Point(mDisplayWidth, mDisplayHeight)); 284 | mPreviewWidth = point.x; 285 | mPreviewHight = point.y; 286 | // Preview 768,432 287 | mPreviewRect.set(0, 0, mPreviewHight, mPreviewWidth); 288 | 289 | mCameraParam.setPreviewSize(mPreviewWidth, mPreviewHight); 290 | mCamera.setParameters(mCameraParam); 291 | 292 | try { 293 | mCamera.setPreviewDisplay(mSurfaceHolder); 294 | mCamera.stopPreview(); 295 | mCamera.setErrorCallback(this); 296 | mCamera.setPreviewCallback(this); 297 | mCamera.startPreview(); 298 | } catch (RuntimeException e) { 299 | e.printStackTrace(); 300 | CameraUtils.releaseCamera(mCamera); 301 | mCamera = null; 302 | } catch (Exception e) { 303 | e.printStackTrace(); 304 | CameraUtils.releaseCamera(mCamera); 305 | mCamera = null; 306 | } 307 | 308 | } 309 | 310 | protected void stopPreview() { 311 | if (mCamera != null) { 312 | try { 313 | mCamera.setErrorCallback(null); 314 | mCamera.setPreviewCallback(null); 315 | mCamera.stopPreview(); 316 | } catch (RuntimeException e) { 317 | e.printStackTrace(); 318 | } catch (Exception e) { 319 | e.printStackTrace(); 320 | } finally { 321 | CameraUtils.releaseCamera(mCamera); 322 | mCamera = null; 323 | } 324 | } 325 | if (mSurfaceHolder != null) { 326 | mSurfaceHolder.removeCallback(this); 327 | } 328 | if (mIDetectStrategy != null) { 329 | mIDetectStrategy = null; 330 | } 331 | } 332 | 333 | private int displayOrientation(Context context) { 334 | WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 335 | int rotation = windowManager.getDefaultDisplay().getRotation(); 336 | int degrees = 0; 337 | switch (rotation) { 338 | case Surface.ROTATION_0: 339 | degrees = 0; 340 | break; 341 | case Surface.ROTATION_90: 342 | degrees = 90; 343 | break; 344 | case Surface.ROTATION_180: 345 | degrees = 180; 346 | break; 347 | case Surface.ROTATION_270: 348 | degrees = 270; 349 | break; 350 | default: 351 | degrees = 0; 352 | break; 353 | } 354 | int result = (0 - degrees + 360) % 360; 355 | if (APIUtils.hasGingerbread()) { 356 | Camera.CameraInfo info = new Camera.CameraInfo(); 357 | Camera.getCameraInfo(mCameraId, info); 358 | if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 359 | result = (info.orientation + degrees) % 360; 360 | result = (360 - result) % 360; 361 | } else { 362 | result = (info.orientation - degrees + 360) % 360; 363 | } 364 | } 365 | return result; 366 | } 367 | 368 | @Override 369 | public void surfaceCreated(SurfaceHolder holder) { 370 | mIsCreateSurface = true; 371 | } 372 | 373 | @Override 374 | public void surfaceChanged(SurfaceHolder holder, 375 | int format, 376 | int width, 377 | int height) { 378 | mSurfaceWidth = width; 379 | mSurfaceHeight = height; 380 | if (holder.getSurface() == null) { 381 | return; 382 | } 383 | startPreview(); 384 | } 385 | 386 | @Override 387 | public void surfaceDestroyed(SurfaceHolder holder) { 388 | mIsCreateSurface = false; 389 | } 390 | 391 | @Override 392 | public void onPreviewFrame(byte[] data, Camera camera) { 393 | 394 | if (mIsCompletion) { 395 | return; 396 | } 397 | 398 | if (mIDetectStrategy == null && mFaceDetectRoundView != null && mFaceDetectRoundView.getRound() > 0) { 399 | mIDetectStrategy = FaceSDKManager.getInstance().getDetectStrategyModule(); 400 | mIDetectStrategy.setPreviewDegree(mPreviewDegree); 401 | mIDetectStrategy.setDetectStrategySoundEnable(mIsEnableSound); 402 | 403 | Rect detectRect = FaceDetectRoundView.getPreviewDetectRect(mDisplayWidth, mPreviewHight, mPreviewWidth); 404 | mIDetectStrategy.setDetectStrategyConfig(mPreviewRect, detectRect, this); 405 | } 406 | if (mIDetectStrategy != null) { 407 | mIDetectStrategy.detectStrategy(data); 408 | } 409 | } 410 | 411 | @Override 412 | public void onError(int error, Camera camera) { 413 | } 414 | 415 | @Override 416 | public void onDetectCompletion(FaceStatusEnum status, String message, 417 | HashMap base64ImageMap) { 418 | if (mIsCompletion) { 419 | return; 420 | } 421 | 422 | onRefreshView(status, message); 423 | 424 | if (status == FaceStatusEnum.OK) { 425 | mIsCompletion = true; 426 | saveImage(base64ImageMap); 427 | } 428 | Ast.getInstance().faceHit("detect"); 429 | } 430 | 431 | private void onRefreshView(FaceStatusEnum status, String message) { 432 | switch (status) { 433 | case OK: 434 | onRefreshTipsView(false, message); 435 | mTipsBottomView.setText(""); 436 | mFaceDetectRoundView.processDrawState(false); 437 | onRefreshSuccessView(true); 438 | break; 439 | case Detect_PitchOutOfUpMaxRange: 440 | case Detect_PitchOutOfDownMaxRange: 441 | case Detect_PitchOutOfLeftMaxRange: 442 | case Detect_PitchOutOfRightMaxRange: 443 | onRefreshTipsView(true, message); 444 | mTipsBottomView.setText(message); 445 | mFaceDetectRoundView.processDrawState(true); 446 | onRefreshSuccessView(false); 447 | break; 448 | default: 449 | onRefreshTipsView(false, message); 450 | mTipsBottomView.setText(""); 451 | mFaceDetectRoundView.processDrawState(true); 452 | onRefreshSuccessView(false); 453 | } 454 | } 455 | 456 | private void onRefreshTipsView(boolean isAlert, String message) { 457 | if (isAlert) { 458 | if (mTipsIcon == null) { 459 | mTipsIcon = getResources().getDrawable(R.mipmap.ic_warning); 460 | mTipsIcon.setBounds(0, 0, (int) (mTipsIcon.getMinimumWidth() * 0.7f), 461 | (int) (mTipsIcon.getMinimumHeight() * 0.7f)); 462 | mTipsTopView.setCompoundDrawablePadding(15); 463 | } 464 | mTipsTopView.setBackgroundResource(R.drawable.bg_tips); 465 | mTipsTopView.setText(R.string.detect_standard); 466 | mTipsTopView.setCompoundDrawables(mTipsIcon, null, null, null); 467 | } else { 468 | mTipsTopView.setBackgroundResource(R.drawable.bg_tips_no); 469 | mTipsTopView.setCompoundDrawables(null, null, null, null); 470 | if (!TextUtils.isEmpty(message)) { 471 | mTipsTopView.setText(message); 472 | } 473 | } 474 | } 475 | 476 | private void onRefreshSuccessView(boolean isShow) { 477 | if (mSuccessView.getTag() == null) { 478 | Rect rect = mFaceDetectRoundView.getFaceRoundRect(); 479 | RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) mSuccessView.getLayoutParams(); 480 | rlp.setMargins( 481 | rect.centerX() - (mSuccessView.getWidth() / 2), 482 | rect.top - (mSuccessView.getHeight() / 2), 483 | 0, 484 | 0); 485 | mSuccessView.setLayoutParams(rlp); 486 | mSuccessView.setTag("setlayout"); 487 | } 488 | mSuccessView.setVisibility(isShow ? View.VISIBLE : View.INVISIBLE); 489 | } 490 | 491 | private void saveImage(HashMap imageMap) { 492 | Set> sets = imageMap.entrySet(); 493 | Bitmap bmp = null; 494 | mImageLayout.removeAllViews(); 495 | for (Map.Entry entry : sets) { 496 | bmp = base64ToBitmap(entry.getValue()); 497 | ImageView iv = new ImageView(this); 498 | iv.setImageBitmap(bmp); 499 | mImageLayout.addView(iv, new LinearLayout.LayoutParams(300, 300)); 500 | } 501 | } 502 | 503 | private static Bitmap base64ToBitmap(String base64Data) { 504 | byte[] bytes = Base64Utils.decode(base64Data, Base64Utils.NO_WRAP); 505 | return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 506 | } 507 | } 508 | -------------------------------------------------------------------------------- /android/src/main/java/com/example/baidu_face_plugin/baidu_face_plugin/FaceDetectExpActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.baidu_face_plugin.baidu_face_plugin; 2 | 3 | import android.content.DialogInterface; 4 | import android.os.Bundle; 5 | 6 | import com.baidu.idl.face.platform.FaceStatusEnum; 7 | 8 | import java.util.HashMap; 9 | 10 | public class FaceDetectExpActivity extends FaceDetectActivity { 11 | 12 | private DefaultDialog mDefaultDialog; 13 | 14 | @Override 15 | public void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | } 18 | 19 | @Override 20 | public void onDetectCompletion(FaceStatusEnum status, String message, HashMap base64ImageMap) { 21 | super.onDetectCompletion(status, message, base64ImageMap); 22 | if (status == FaceStatusEnum.OK && mIsCompletion) { 23 | this.getIntent().putExtra("success", true); 24 | // map中包含所有动作照片,另外会记录一张bestImage0 25 | this.getIntent().putExtra("image", base64ImageMap.get("bestImage0")); 26 | this.setResult(10013, this.getIntent()); 27 | finish(); 28 | // showMessageDialog("人脸图像采集", "采集成功"); 29 | } else if (status == FaceStatusEnum.Error_DetectTimeout || 30 | status == FaceStatusEnum.Error_LivenessTimeout || 31 | status == FaceStatusEnum.Error_Timeout) { 32 | this.getIntent().putExtra("success", false); 33 | this.setResult(10013, this.getIntent()); 34 | finish(); 35 | // showMessageDialog("人脸图像采集", "采集超时"); 36 | } 37 | } 38 | 39 | private void showMessageDialog(String title, String message) { 40 | if (mDefaultDialog == null) { 41 | DefaultDialog.Builder builder = new DefaultDialog.Builder(this); 42 | builder.setTitle(title). 43 | setMessage(message). 44 | setNegativeButton("确认", 45 | new DialogInterface.OnClickListener() { 46 | @Override 47 | public void onClick(DialogInterface dialog, int which) { 48 | mDefaultDialog.dismiss(); 49 | finish(); 50 | } 51 | }); 52 | mDefaultDialog = builder.create(); 53 | mDefaultDialog.setCancelable(true); 54 | } 55 | mDefaultDialog.dismiss(); 56 | mDefaultDialog.show(); 57 | } 58 | 59 | @Override 60 | public void finish() { 61 | super.finish(); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /android/src/main/java/com/example/baidu_face_plugin/baidu_face_plugin/FaceDetectRoundView.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017 Baidu Inc. All rights reserved. 3 | */ 4 | package com.example.baidu_face_plugin.baidu_face_plugin; 5 | 6 | import android.content.Context; 7 | import android.graphics.Canvas; 8 | import android.graphics.Color; 9 | import android.graphics.DashPathEffect; 10 | import android.graphics.Paint; 11 | import android.graphics.PathEffect; 12 | import android.graphics.PorterDuff; 13 | import android.graphics.PorterDuffXfermode; 14 | import android.graphics.Rect; 15 | import android.util.AttributeSet; 16 | import android.util.DisplayMetrics; 17 | import android.util.Log; 18 | import android.view.View; 19 | 20 | import com.baidu.idl.face.platform.utils.DensityUtils; 21 | 22 | /** 23 | * 人脸检测区域View 24 | */ 25 | public class FaceDetectRoundView extends View { 26 | 27 | private static final String TAG = FaceDetectRoundView.class.getSimpleName(); 28 | 29 | public static final float SURFACE_HEIGHT = 1000f; 30 | public static final float SURFACE_RATIO = 0.75f; 31 | public static final float WIDTH_SPACE_RATIO = 0.33f; 32 | public static final float HEIGHT_RATIO = 0.1f; 33 | public static final float HEIGHT_EXT_RATIO = 0.2f; 34 | public static final int CIRCLE_SPACE = 5; 35 | public static final int PATH_SPACE = 16; 36 | public static final int PATH_SMALL_SPACE = 12; 37 | public static final int PATH_WIDTH = 4; 38 | 39 | // public static final int COLOR_BG = Color.parseColor("#2F2F33"); 40 | // public static final int COLOR_RECT = Color.parseColor("#FFFFFF"); 41 | // public static final int COLOR_ROUND = Color.parseColor("#FFA800"); 42 | 43 | private PathEffect mFaceRoundPathEffect = null; 44 | // new DashPathEffect(new float[]{PATH_SPACE, PATH_SPACE}, 1); 45 | private Paint mBGPaint; 46 | private Paint mPathPaint; 47 | private Paint mFaceRectPaint; 48 | private Paint mFaceRoundPaint; 49 | private Rect mFaceRect; 50 | private Rect mFaceDetectRect; 51 | 52 | private float mX; 53 | private float mY; 54 | private float mR; 55 | private boolean mIsDrawDash = true; 56 | 57 | public FaceDetectRoundView(Context context, AttributeSet attrs) { 58 | super(context, attrs); 59 | 60 | setLayerType(View.LAYER_TYPE_SOFTWARE, null); 61 | 62 | DisplayMetrics dm = context.getResources().getDisplayMetrics(); 63 | float pathSpace = DensityUtils.dip2px(context, PATH_SPACE); 64 | float pathSmallSpace = DensityUtils.dip2px(context, PATH_SMALL_SPACE); 65 | float pathWidth = DensityUtils.dip2px(context, PATH_WIDTH); 66 | mFaceRoundPathEffect = new DashPathEffect( 67 | new float[]{pathSpace, dm.heightPixels < SURFACE_HEIGHT 68 | ? pathSmallSpace : pathSpace}, 1); 69 | 70 | mBGPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 71 | mBGPaint.setColor(getResources().getColor(R.color.FACE_DETECT_ROUND_VIEW_COLOR_BG)); 72 | mBGPaint.setStyle(Paint.Style.FILL); 73 | mBGPaint.setAntiAlias(true); 74 | mBGPaint.setDither(true); 75 | 76 | mPathPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 77 | mPathPaint.setColor(getResources().getColor(R.color.FACE_DETECT_ROUND_VIEW_COLOR_ROUND)); 78 | mPathPaint.setStrokeWidth(pathWidth); 79 | mPathPaint.setStyle(Paint.Style.STROKE); 80 | mPathPaint.setAntiAlias(true); 81 | mPathPaint.setDither(true); 82 | 83 | mFaceRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 84 | mFaceRectPaint.setColor(getResources().getColor(R.color.FACE_DETECT_ROUND_VIEW_COLOR_RECT)); 85 | mFaceRectPaint.setStrokeWidth(pathWidth); 86 | mFaceRectPaint.setStyle(Paint.Style.STROKE); 87 | mFaceRectPaint.setAntiAlias(true); 88 | mFaceRectPaint.setDither(true); 89 | 90 | mFaceRoundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 91 | mFaceRoundPaint.setColor(getResources().getColor(R.color.FACE_DETECT_ROUND_VIEW_COLOR_ROUND)); 92 | mFaceRoundPaint.setStyle(Paint.Style.FILL); 93 | mFaceRoundPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 94 | mFaceRoundPaint.setAntiAlias(true); 95 | mFaceRoundPaint.setDither(true); 96 | } 97 | 98 | public void processDrawState(boolean isDrawDash) { 99 | mIsDrawDash = isDrawDash; 100 | postInvalidate(); 101 | } 102 | 103 | public float getRound() { 104 | return mR; 105 | } 106 | 107 | public Rect getFaceRoundRect() { 108 | if (mFaceRect != null) { 109 | Log.e(TAG, mFaceRect.toString()); 110 | } 111 | return mFaceRect; 112 | } 113 | 114 | @Override 115 | protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 116 | float canvasWidth = right - left; 117 | float canvasHeight = bottom - top; 118 | 119 | float x = canvasWidth / 2; 120 | float y = (canvasHeight / 2) - ((canvasHeight / 2) * HEIGHT_RATIO); 121 | float r = (canvasWidth / 2) - ((canvasWidth / 2) * WIDTH_SPACE_RATIO); 122 | 123 | if (mFaceRect == null) { 124 | mFaceRect = new Rect((int) (x - r), 125 | (int) (y - r), 126 | (int) (x + r), 127 | (int) (y + r)); 128 | } 129 | if (mFaceDetectRect == null) { 130 | float hr = r + (r * HEIGHT_EXT_RATIO); 131 | mFaceDetectRect = new Rect((int) (x - r), 132 | (int) (y - hr), 133 | (int) (x + r), 134 | (int) (y + hr)); 135 | } 136 | mX = x; 137 | mY = y; 138 | mR = r; 139 | } 140 | 141 | @Override 142 | public void onDraw(Canvas canvas) { 143 | super.onDraw(canvas); 144 | canvas.drawColor(Color.TRANSPARENT); 145 | canvas.drawPaint(mBGPaint); 146 | if (mIsDrawDash) { 147 | mPathPaint.setPathEffect(mFaceRoundPathEffect); 148 | } else { 149 | mPathPaint.setPathEffect(null); 150 | } 151 | canvas.drawCircle(mX, mY, mR + CIRCLE_SPACE, mPathPaint); 152 | canvas.drawCircle(mX, mY, mR, mFaceRoundPaint); 153 | // if (mFaceRect != null) { 154 | // canvas.drawRect(mFaceRect, mFaceRectPaint); 155 | // } 156 | // if (mFaceDetectRect != null) { 157 | // canvas.drawRect(mFaceDetectRect, mFaceRectPaint); 158 | // } 159 | } 160 | 161 | public static Rect getPreviewDetectRect(int w, int pw, int ph) { 162 | float round = (w / 2) - ((w / 2) * WIDTH_SPACE_RATIO); 163 | float x = pw / 2; 164 | float y = (ph / 2) - ((ph / 2) * HEIGHT_RATIO); 165 | float r = (pw / 2) > round ? round : (pw / 2); 166 | float hr = r + (r * HEIGHT_EXT_RATIO); 167 | Rect rect = new Rect((int) (x - r), 168 | (int) (y - hr), 169 | (int) (x + r), 170 | (int) (y + hr)); 171 | // Log.e(TAG, "FaceRoundView getPreviewDetectRect " + pw + "-" + ph + "-" + rect.toString()); 172 | return rect; 173 | } 174 | 175 | } -------------------------------------------------------------------------------- /android/src/main/java/com/example/baidu_face_plugin/baidu_face_plugin/FaceLivenessActivity.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017 Baidu Inc. All rights reserved. 3 | */ 4 | package com.example.baidu_face_plugin.baidu_face_plugin; 5 | 6 | import android.app.Activity; 7 | import android.content.BroadcastReceiver; 8 | import android.content.Context; 9 | import android.graphics.Bitmap; 10 | import android.graphics.BitmapFactory; 11 | import android.graphics.PixelFormat; 12 | import android.graphics.Point; 13 | import android.graphics.Rect; 14 | import android.graphics.drawable.Drawable; 15 | import android.hardware.Camera; 16 | import android.media.AudioManager; 17 | import android.os.Bundle; 18 | import android.text.TextUtils; 19 | import android.util.DisplayMetrics; 20 | import android.util.Log; 21 | import android.view.Display; 22 | import android.view.Gravity; 23 | import android.view.Surface; 24 | import android.view.SurfaceHolder; 25 | import android.view.SurfaceView; 26 | import android.view.View; 27 | import android.view.WindowManager; 28 | import android.widget.FrameLayout; 29 | import android.widget.ImageView; 30 | import android.widget.LinearLayout; 31 | import android.widget.RelativeLayout; 32 | import android.widget.TextView; 33 | 34 | import com.baidu.aip.face.stat.Ast; 35 | import com.baidu.idl.face.platform.FaceConfig; 36 | import com.baidu.idl.face.platform.FaceSDKManager; 37 | import com.baidu.idl.face.platform.FaceStatusEnum; 38 | import com.baidu.idl.face.platform.ILivenessStrategy; 39 | import com.baidu.idl.face.platform.ILivenessStrategyCallback; 40 | import com.baidu.idl.face.platform.utils.APIUtils; 41 | import com.baidu.idl.face.platform.utils.Base64Utils; 42 | import com.baidu.idl.face.platform.utils.CameraPreviewUtils; 43 | 44 | import java.util.HashMap; 45 | import java.util.Map; 46 | import java.util.Set; 47 | 48 | /** 49 | * 活体检测接口 50 | */ 51 | public class FaceLivenessActivity extends Activity implements 52 | SurfaceHolder.Callback, 53 | Camera.PreviewCallback, 54 | Camera.ErrorCallback, 55 | VolumeUtils.VolumeCallback, 56 | ILivenessStrategyCallback { 57 | 58 | public static final String TAG = FaceLivenessActivity.class.getSimpleName(); 59 | 60 | // View 61 | protected View mRootView; 62 | protected FrameLayout mFrameLayout; 63 | protected SurfaceView mSurfaceView; 64 | protected SurfaceHolder mSurfaceHolder; 65 | protected ImageView mCloseView; 66 | protected ImageView mSoundView; 67 | protected ImageView mSuccessView; 68 | protected TextView mTipsTopView; 69 | protected TextView mTipsBottomView; 70 | protected FaceDetectRoundView mFaceDetectRoundView; 71 | protected LinearLayout mImageLayout; 72 | // 人脸信息 73 | protected FaceConfig mFaceConfig; 74 | protected ILivenessStrategy mILivenessStrategy; 75 | // 显示Size 76 | private Rect mPreviewRect = new Rect(); 77 | protected int mDisplayWidth = 0; 78 | protected int mDisplayHeight = 0; 79 | protected int mSurfaceWidth = 0; 80 | protected int mSurfaceHeight = 0; 81 | protected Drawable mTipsIcon; 82 | // 状态标识 83 | protected volatile boolean mIsEnableSound = true; 84 | protected HashMap mBase64ImageMap = new HashMap(); 85 | protected boolean mIsCreateSurface = false; 86 | protected boolean mIsCompletion = false; 87 | // 相机 88 | protected Camera mCamera; 89 | protected Camera.Parameters mCameraParam; 90 | protected int mCameraId; 91 | protected int mPreviewWidth; 92 | protected int mPreviewHight; 93 | protected int mPreviewDegree; 94 | // 监听系统音量广播 95 | protected BroadcastReceiver mVolumeReceiver; 96 | 97 | @Override 98 | public void onCreate(Bundle savedInstanceState) { 99 | super.onCreate(savedInstanceState); 100 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 101 | setContentView(R.layout.activity_face_liveness_v3100); 102 | DisplayMetrics dm = new DisplayMetrics(); 103 | Display display = this.getWindowManager().getDefaultDisplay(); 104 | display.getMetrics(dm); 105 | mDisplayWidth = dm.widthPixels; 106 | mDisplayHeight = dm.heightPixels; 107 | 108 | String language = this.getIntent().getStringExtra("language"); 109 | language = (language == null || "".equals(language)) ? "zh" : language; 110 | FaceSDKResSettings.changeResLanguage(language); 111 | 112 | mFaceConfig = FaceSDKManager.getInstance().getFaceConfig(); 113 | 114 | AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 115 | int vol = am.getStreamVolume(AudioManager.STREAM_MUSIC); 116 | mIsEnableSound = vol > 0 ? mFaceConfig.isSound : false; 117 | 118 | mRootView = this.findViewById(R.id.liveness_root_layout); 119 | mFrameLayout = (FrameLayout) mRootView.findViewById(R.id.liveness_surface_layout); 120 | 121 | mSurfaceView = new SurfaceView(this); 122 | mSurfaceHolder = mSurfaceView.getHolder(); 123 | mSurfaceHolder.setSizeFromLayout(); 124 | mSurfaceHolder.addCallback(this); 125 | mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 126 | 127 | int w = mDisplayWidth; 128 | int h = mDisplayHeight; 129 | 130 | FrameLayout.LayoutParams cameraFL = new FrameLayout.LayoutParams( 131 | (int) (w * FaceDetectRoundView.SURFACE_RATIO), (int) (h * FaceDetectRoundView.SURFACE_RATIO), 132 | Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL); 133 | 134 | mSurfaceView.setLayoutParams(cameraFL); 135 | mFrameLayout.addView(mSurfaceView); 136 | 137 | mRootView.findViewById(R.id.liveness_close).setOnClickListener(new View.OnClickListener() { 138 | @Override 139 | public void onClick(View v) { 140 | onBackPressed(); 141 | } 142 | }); 143 | 144 | mFaceDetectRoundView = (FaceDetectRoundView) mRootView.findViewById(R.id.liveness_face_round); 145 | mCloseView = (ImageView) mRootView.findViewById(R.id.liveness_close); 146 | mSoundView = (ImageView) mRootView.findViewById(R.id.liveness_sound); 147 | mSoundView.setImageResource(mIsEnableSound ? 148 | R.mipmap.ic_enable_sound_ext : R.mipmap.ic_disable_sound_ext); 149 | mSoundView.setOnClickListener(new View.OnClickListener() { 150 | @Override 151 | public void onClick(View v) { 152 | mIsEnableSound = !mIsEnableSound; 153 | mSoundView.setImageResource(mIsEnableSound ? 154 | R.mipmap.ic_enable_sound_ext : R.mipmap.ic_disable_sound_ext); 155 | if (mILivenessStrategy != null) { 156 | mILivenessStrategy.setLivenessStrategySoundEnable(mIsEnableSound); 157 | } 158 | } 159 | }); 160 | mTipsTopView = (TextView) mRootView.findViewById(R.id.liveness_top_tips); 161 | mTipsBottomView = (TextView) mRootView.findViewById(R.id.liveness_bottom_tips); 162 | mSuccessView = (ImageView) mRootView.findViewById(R.id.liveness_success_image); 163 | 164 | mImageLayout = (LinearLayout) mRootView.findViewById(R.id.liveness_result_image_layout); 165 | if (mBase64ImageMap != null) { 166 | mBase64ImageMap.clear(); 167 | } 168 | } 169 | 170 | @Override 171 | public void onResume() { 172 | super.onResume(); 173 | setVolumeControlStream(AudioManager.STREAM_MUSIC); 174 | mVolumeReceiver = VolumeUtils.registerVolumeReceiver(this, this); 175 | if (mTipsTopView != null) { 176 | mTipsTopView.setText(R.string.detect_face_in); 177 | } 178 | startPreview(); 179 | } 180 | 181 | @Override 182 | public void onPause() { 183 | super.onPause(); 184 | stopPreview(); 185 | } 186 | 187 | @Override 188 | public void onStop() { 189 | if (mILivenessStrategy != null) { 190 | mILivenessStrategy.reset(); 191 | } 192 | VolumeUtils.unRegisterVolumeReceiver(this, mVolumeReceiver); 193 | mVolumeReceiver = null; 194 | super.onStop(); 195 | stopPreview(); 196 | } 197 | 198 | @Override 199 | public void finish() { 200 | super.finish(); 201 | } 202 | 203 | @Override 204 | public void volumeChanged() { 205 | try { 206 | AudioManager am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE); 207 | if (am != null) { 208 | int cv = am.getStreamVolume(AudioManager.STREAM_MUSIC); 209 | mIsEnableSound = cv > 0; 210 | mSoundView.setImageResource(mIsEnableSound 211 | ? R.mipmap.ic_enable_sound_ext : R.mipmap.ic_disable_sound_ext); 212 | if (mILivenessStrategy != null) { 213 | mILivenessStrategy.setLivenessStrategySoundEnable(mIsEnableSound); 214 | } 215 | } 216 | } catch (Exception ex) { 217 | ex.printStackTrace(); 218 | } 219 | } 220 | 221 | private Camera open() { 222 | Camera camera; 223 | int numCameras = Camera.getNumberOfCameras(); 224 | if (numCameras == 0) { 225 | return null; 226 | } 227 | 228 | int index = 0; 229 | while (index < numCameras) { 230 | Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); 231 | Camera.getCameraInfo(index, cameraInfo); 232 | if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 233 | break; 234 | } 235 | index++; 236 | } 237 | 238 | if (index < numCameras) { 239 | camera = Camera.open(index); 240 | mCameraId = index; 241 | } else { 242 | camera = Camera.open(0); 243 | mCameraId = 0; 244 | } 245 | return camera; 246 | } 247 | 248 | protected void startPreview() { 249 | if (mSurfaceView != null && mSurfaceView.getHolder() != null) { 250 | mSurfaceHolder = mSurfaceView.getHolder(); 251 | mSurfaceHolder.addCallback(this); 252 | } 253 | 254 | if (mCamera == null) { 255 | try { 256 | mCamera = open(); 257 | } catch (RuntimeException e) { 258 | e.printStackTrace(); 259 | } catch (Exception e) { 260 | e.printStackTrace(); 261 | } 262 | } 263 | 264 | if (mCamera == null) { 265 | return; 266 | } 267 | 268 | if (mCameraParam == null) { 269 | mCameraParam = mCamera.getParameters(); 270 | } 271 | 272 | mCameraParam.setPictureFormat(PixelFormat.JPEG); 273 | int degree = displayOrientation(this); 274 | mCamera.setDisplayOrientation(degree); 275 | // 设置后无效,camera.setDisplayOrientation方法有效 276 | mCameraParam.set("rotation", degree); 277 | mPreviewDegree = degree; 278 | 279 | Point point = CameraPreviewUtils.getBestPreview(mCameraParam, 280 | new Point(mDisplayWidth, mDisplayHeight)); 281 | 282 | mPreviewWidth = point.x; 283 | mPreviewHight = point.y; 284 | // Preview 768,432 285 | 286 | if (mILivenessStrategy != null) { 287 | mILivenessStrategy.setPreviewDegree(degree); 288 | } 289 | 290 | mPreviewRect.set(0, 0, mPreviewHight, mPreviewWidth); 291 | 292 | mCameraParam.setPreviewSize(mPreviewWidth, mPreviewHight); 293 | mCamera.setParameters(mCameraParam); 294 | 295 | try { 296 | mCamera.setPreviewDisplay(mSurfaceHolder); 297 | mCamera.stopPreview(); 298 | mCamera.setErrorCallback(this); 299 | mCamera.setPreviewCallback(this); 300 | mCamera.startPreview(); 301 | } catch (RuntimeException e) { 302 | e.printStackTrace(); 303 | CameraUtils.releaseCamera(mCamera); 304 | mCamera = null; 305 | } catch (Exception e) { 306 | e.printStackTrace(); 307 | CameraUtils.releaseCamera(mCamera); 308 | mCamera = null; 309 | } 310 | } 311 | 312 | protected void stopPreview() { 313 | if (mCamera != null) { 314 | try { 315 | mCamera.setErrorCallback(null); 316 | mCamera.setPreviewCallback(null); 317 | mCamera.stopPreview(); 318 | } catch (RuntimeException e) { 319 | e.printStackTrace(); 320 | } catch (Exception e) { 321 | e.printStackTrace(); 322 | } finally { 323 | CameraUtils.releaseCamera(mCamera); 324 | mCamera = null; 325 | } 326 | } 327 | if (mSurfaceHolder != null) { 328 | mSurfaceHolder.removeCallback(this); 329 | } 330 | if (mILivenessStrategy != null) { 331 | mILivenessStrategy = null; 332 | } 333 | } 334 | 335 | private int displayOrientation(Context context) { 336 | WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 337 | int rotation = windowManager.getDefaultDisplay().getRotation(); 338 | int degrees = 0; 339 | switch (rotation) { 340 | case Surface.ROTATION_0: 341 | degrees = 0; 342 | break; 343 | case Surface.ROTATION_90: 344 | degrees = 90; 345 | break; 346 | case Surface.ROTATION_180: 347 | degrees = 180; 348 | break; 349 | case Surface.ROTATION_270: 350 | degrees = 270; 351 | break; 352 | default: 353 | degrees = 0; 354 | break; 355 | } 356 | int result = (0 - degrees + 360) % 360; 357 | if (APIUtils.hasGingerbread()) { 358 | Camera.CameraInfo info = new Camera.CameraInfo(); 359 | Camera.getCameraInfo(mCameraId, info); 360 | if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 361 | result = (info.orientation + degrees) % 360; 362 | result = (360 - result) % 360; 363 | } else { 364 | result = (info.orientation - degrees + 360) % 360; 365 | } 366 | } 367 | return result; 368 | } 369 | 370 | @Override 371 | public void surfaceCreated(SurfaceHolder holder) { 372 | mIsCreateSurface = true; 373 | } 374 | 375 | @Override 376 | public void surfaceChanged(SurfaceHolder holder, 377 | int format, 378 | int width, 379 | int height) { 380 | mSurfaceWidth = width; 381 | mSurfaceHeight = height; 382 | if (holder.getSurface() == null) { 383 | return; 384 | } 385 | startPreview(); 386 | } 387 | 388 | @Override 389 | public void surfaceDestroyed(SurfaceHolder holder) { 390 | mIsCreateSurface = false; 391 | } 392 | 393 | @Override 394 | public void onPreviewFrame(byte[] data, Camera camera) { 395 | 396 | if (mIsCompletion) { 397 | return; 398 | } 399 | 400 | if (mILivenessStrategy == null) { 401 | mILivenessStrategy = FaceSDKManager.getInstance().getLivenessStrategyModule(); 402 | mILivenessStrategy.setPreviewDegree(mPreviewDegree); 403 | mILivenessStrategy.setLivenessStrategySoundEnable(mIsEnableSound); 404 | 405 | Rect detectRect = FaceDetectRoundView.getPreviewDetectRect( 406 | mDisplayWidth, mPreviewHight, mPreviewWidth); 407 | mILivenessStrategy.setLivenessStrategyConfig( 408 | mFaceConfig.getLivenessTypeList(), mPreviewRect, detectRect, this); 409 | } 410 | mILivenessStrategy.livenessStrategy(data); 411 | } 412 | 413 | @Override 414 | public void onError(int error, Camera camera) { 415 | } 416 | 417 | @Override 418 | public void onLivenessCompletion(FaceStatusEnum status, String message, 419 | HashMap base64ImageMap) { 420 | if (mIsCompletion) { 421 | return; 422 | } 423 | 424 | onRefreshView(status, message); 425 | 426 | if (status == FaceStatusEnum.OK) { 427 | mIsCompletion = true; 428 | saveImage(base64ImageMap); 429 | } 430 | Ast.getInstance().faceHit("liveness"); 431 | } 432 | 433 | private void onRefreshView(FaceStatusEnum status, String message) { 434 | switch (status) { 435 | case OK: 436 | case Liveness_OK: 437 | case Liveness_Completion: 438 | onRefreshTipsView(false, message); 439 | mTipsBottomView.setText(""); 440 | mFaceDetectRoundView.processDrawState(false); 441 | onRefreshSuccessView(true); 442 | break; 443 | case Detect_DataNotReady: 444 | case Liveness_Eye: 445 | case Liveness_Mouth: 446 | case Liveness_HeadUp: 447 | case Liveness_HeadDown: 448 | case Liveness_HeadLeft: 449 | case Liveness_HeadRight: 450 | case Liveness_HeadLeftRight: 451 | onRefreshTipsView(false, message); 452 | mTipsBottomView.setText(""); 453 | mFaceDetectRoundView.processDrawState(false); 454 | onRefreshSuccessView(false); 455 | break; 456 | case Detect_PitchOutOfUpMaxRange: 457 | case Detect_PitchOutOfDownMaxRange: 458 | case Detect_PitchOutOfLeftMaxRange: 459 | case Detect_PitchOutOfRightMaxRange: 460 | onRefreshTipsView(true, message); 461 | mTipsBottomView.setText(message); 462 | mFaceDetectRoundView.processDrawState(true); 463 | onRefreshSuccessView(false); 464 | break; 465 | default: 466 | onRefreshTipsView(false, message); 467 | mTipsBottomView.setText(""); 468 | mFaceDetectRoundView.processDrawState(true); 469 | onRefreshSuccessView(false); 470 | } 471 | } 472 | 473 | private void onRefreshTipsView(boolean isAlert, String message) { 474 | if (isAlert) { 475 | if (mTipsIcon == null) { 476 | mTipsIcon = getResources().getDrawable(R.mipmap.ic_warning); 477 | mTipsIcon.setBounds(0, 0, (int) (mTipsIcon.getMinimumWidth() * 0.7f), 478 | (int) (mTipsIcon.getMinimumHeight() * 0.7f)); 479 | mTipsTopView.setCompoundDrawablePadding(15); 480 | } 481 | mTipsTopView.setBackgroundResource(R.drawable.bg_tips); 482 | mTipsTopView.setText(R.string.detect_standard); 483 | mTipsTopView.setCompoundDrawables(mTipsIcon, null, null, null); 484 | } else { 485 | mTipsTopView.setBackgroundResource(R.drawable.bg_tips_no); 486 | mTipsTopView.setCompoundDrawables(null, null, null, null); 487 | if (!TextUtils.isEmpty(message)) { 488 | mTipsTopView.setText(message); 489 | } 490 | } 491 | } 492 | 493 | private void onRefreshSuccessView(boolean isShow) { 494 | if (mSuccessView.getTag() == null) { 495 | Rect rect = mFaceDetectRoundView.getFaceRoundRect(); 496 | RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) mSuccessView.getLayoutParams(); 497 | rlp.setMargins( 498 | rect.centerX() - (mSuccessView.getWidth() / 2), 499 | rect.top - (mSuccessView.getHeight() / 2), 500 | 0, 501 | 0); 502 | mSuccessView.setLayoutParams(rlp); 503 | mSuccessView.setTag("setlayout"); 504 | } 505 | mSuccessView.setVisibility(isShow ? View.VISIBLE : View.INVISIBLE); 506 | } 507 | 508 | private void saveImage(HashMap imageMap) { 509 | Set> sets = imageMap.entrySet(); 510 | Bitmap bmp = null; 511 | mImageLayout.removeAllViews(); 512 | for (Map.Entry entry : sets) { 513 | bmp = base64ToBitmap(entry.getValue()); 514 | ImageView iv = new ImageView(this); 515 | iv.setImageBitmap(bmp); 516 | mImageLayout.addView(iv, new LinearLayout.LayoutParams(300, 300)); 517 | } 518 | } 519 | 520 | private static Bitmap base64ToBitmap(String base64Data) { 521 | byte[] bytes = Base64Utils.decode(base64Data, Base64Utils.NO_WRAP); 522 | return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 523 | } 524 | 525 | } 526 | -------------------------------------------------------------------------------- /android/src/main/java/com/example/baidu_face_plugin/baidu_face_plugin/FaceLivenessExpActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.baidu_face_plugin.baidu_face_plugin; 2 | 3 | import android.content.DialogInterface; 4 | import android.os.Bundle; 5 | 6 | import com.baidu.idl.face.platform.FaceStatusEnum; 7 | 8 | import java.util.HashMap; 9 | 10 | public class FaceLivenessExpActivity extends FaceLivenessActivity { 11 | 12 | private DefaultDialog mDefaultDialog; 13 | 14 | @Override 15 | public void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | } 18 | 19 | @Override 20 | public void onLivenessCompletion(FaceStatusEnum status, String message, HashMap base64ImageMap) { 21 | super.onLivenessCompletion(status, message, base64ImageMap); 22 | if (status == FaceStatusEnum.OK && mIsCompletion) { 23 | this.getIntent().putExtra("success", true); 24 | // map中包含所有动作照片,另外会记录一张bestImage0 25 | this.getIntent().putExtra("image", base64ImageMap.get("bestImage0")); 26 | this.setResult(10013, this.getIntent()); 27 | finish(); 28 | // showMessageDialog("活体检测", "检测成功"); 29 | } else if (status == FaceStatusEnum.Error_DetectTimeout || 30 | status == FaceStatusEnum.Error_LivenessTimeout || 31 | status == FaceStatusEnum.Error_Timeout) { 32 | this.getIntent().putExtra("success", false); 33 | this.setResult(10013, this.getIntent()); 34 | finish(); 35 | // showMessageDialog("活体检测", "采集超时"); 36 | } 37 | } 38 | 39 | private void showMessageDialog(String title, String message) { 40 | if (mDefaultDialog == null) { 41 | DefaultDialog.Builder builder = new DefaultDialog.Builder(this); 42 | builder.setTitle(title). 43 | setMessage(message). 44 | setNegativeButton("确认", 45 | new DialogInterface.OnClickListener() { 46 | @Override 47 | public void onClick(DialogInterface dialog, int which) { 48 | mDefaultDialog.dismiss(); 49 | finish(); 50 | } 51 | }); 52 | mDefaultDialog = builder.create(); 53 | mDefaultDialog.setCancelable(true); 54 | } 55 | mDefaultDialog.dismiss(); 56 | mDefaultDialog.show(); 57 | } 58 | 59 | @Override 60 | public void finish() { 61 | super.finish(); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /android/src/main/java/com/example/baidu_face_plugin/baidu_face_plugin/FaceSDKResSettings.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017 Baidu Inc. All rights reserved. 3 | */ 4 | package com.example.baidu_face_plugin.baidu_face_plugin; 5 | 6 | import com.baidu.idl.face.platform.FaceEnvironment; 7 | import com.baidu.idl.face.platform.FaceStatusEnum; 8 | 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * sdk使用Res资源设置功能 14 | */ 15 | public class FaceSDKResSettings { 16 | 17 | // map> 18 | private static final Map> soundMap = new HashMap<>(); 19 | private static final Map> tipsMap = new HashMap<>(); 20 | 21 | public static void initResMaps(Map> _soundMap, Map> _tipsMap) { 22 | soundMap.clear(); 23 | soundMap.putAll(_soundMap); 24 | tipsMap.clear(); 25 | tipsMap.putAll(_tipsMap); 26 | } 27 | 28 | public static void changeResLanguage(String language) { 29 | if (language == null || "".equals(language) || soundMap.get(language) == null || tipsMap.get(language) == null) { 30 | throw new RuntimeException("language is not supported: " + language); 31 | } 32 | 33 | for (Map.Entry e : soundMap.get(language).entrySet()) { 34 | FaceEnvironment.setSoundId(e.getKey(), e.getValue()); 35 | } 36 | 37 | for (Map.Entry e : tipsMap.get(language).entrySet()) { 38 | FaceEnvironment.setTipsId(e.getKey(), e.getValue()); 39 | } 40 | 41 | // // Sound Res Id 42 | // FaceEnvironment.setSoundId(FaceStatusEnum.Detect_NoFace, R.raw.detect_face_in); 43 | // FaceEnvironment.setSoundId(FaceStatusEnum.Detect_FacePointOut, R.raw.detect_face_in); 44 | // FaceEnvironment.setSoundId(FaceStatusEnum.Liveness_Eye, R.raw.liveness_eye); 45 | // FaceEnvironment.setSoundId(FaceStatusEnum.Liveness_Mouth, R.raw.liveness_mouth); 46 | // FaceEnvironment.setSoundId(FaceStatusEnum.Liveness_HeadUp, R.raw.liveness_head_up); 47 | // FaceEnvironment.setSoundId(FaceStatusEnum.Liveness_HeadDown, R.raw.liveness_head_down); 48 | // FaceEnvironment.setSoundId(FaceStatusEnum.Liveness_HeadLeft, R.raw.liveness_head_left); 49 | // FaceEnvironment.setSoundId(FaceStatusEnum.Liveness_HeadRight, R.raw.liveness_head_right); 50 | // FaceEnvironment.setSoundId(FaceStatusEnum.Liveness_HeadLeftRight, R.raw.liveness_head_left_right); 51 | // FaceEnvironment.setSoundId(FaceStatusEnum.Liveness_OK, R.raw.face_good); 52 | // FaceEnvironment.setSoundId(FaceStatusEnum.OK, R.raw.face_good); 53 | // 54 | // // Tips Res Id 55 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_NoFace, R.string.detect_no_face); 56 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_FacePointOut, R.string.detect_face_in); 57 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_PoorIllumintion, R.string.detect_low_light); 58 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_ImageBlured, R.string.detect_keep); 59 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_OccLeftEye, R.string.detect_occ_face); 60 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_OccRightEye, R.string.detect_occ_face); 61 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_OccNose, R.string.detect_occ_face); 62 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_OccMouth, R.string.detect_occ_face); 63 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_OccLeftContour, R.string.detect_occ_face); 64 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_OccRightContour, R.string.detect_occ_face); 65 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_OccChin, R.string.detect_occ_face); 66 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_PitchOutOfUpMaxRange, R.string.detect_head_down); 67 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_PitchOutOfDownMaxRange, R.string.detect_head_up); 68 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_PitchOutOfLeftMaxRange, R.string.detect_head_right); 69 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_PitchOutOfRightMaxRange, R.string.detect_head_left); 70 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_FaceZoomIn, R.string.detect_zoom_in); 71 | // FaceEnvironment.setTipsId(FaceStatusEnum.Detect_FaceZoomOut, R.string.detect_zoom_out); 72 | // 73 | // FaceEnvironment.setTipsId(FaceStatusEnum.Liveness_Eye, R.string.liveness_eye); 74 | // FaceEnvironment.setTipsId(FaceStatusEnum.Liveness_Mouth, R.string.liveness_mouth); 75 | // FaceEnvironment.setTipsId(FaceStatusEnum.Liveness_HeadUp, R.string.liveness_head_up); 76 | // FaceEnvironment.setTipsId(FaceStatusEnum.Liveness_HeadDown, R.string.liveness_head_down); 77 | // FaceEnvironment.setTipsId(FaceStatusEnum.Liveness_HeadLeft, R.string.liveness_head_left); 78 | // FaceEnvironment.setTipsId(FaceStatusEnum.Liveness_HeadRight, R.string.liveness_head_right); 79 | // FaceEnvironment.setTipsId(FaceStatusEnum.Liveness_HeadLeftRight, R.string.liveness_head_left_right); 80 | // FaceEnvironment.setTipsId(FaceStatusEnum.Liveness_OK, R.string.liveness_good); 81 | // FaceEnvironment.setTipsId(FaceStatusEnum.OK, R.string.liveness_good); 82 | // 83 | // FaceEnvironment.setTipsId(FaceStatusEnum.Error_Timeout, R.string.detect_timeout); 84 | // FaceEnvironment.setTipsId(FaceStatusEnum.Error_DetectTimeout, R.string.detect_timeout); 85 | // FaceEnvironment.setTipsId(FaceStatusEnum.Error_LivenessTimeout, R.string.detect_timeout); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /android/src/main/java/com/example/baidu_face_plugin/baidu_face_plugin/VolumeUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017 Baidu Inc. All rights reserved. 3 | */ 4 | package com.example.baidu_face_plugin.baidu_face_plugin; 5 | 6 | import android.content.BroadcastReceiver; 7 | import android.content.Context; 8 | import android.content.Intent; 9 | import android.content.IntentFilter; 10 | import android.util.Log; 11 | 12 | /** 13 | * VolumeUtils 14 | * 描述:系统音量监听 15 | */ 16 | public class VolumeUtils { 17 | 18 | public static final String TAG = VolumeUtils.class.getSimpleName(); 19 | 20 | public interface VolumeCallback { 21 | void volumeChanged(); 22 | } 23 | 24 | public static class VolumeReceiver extends BroadcastReceiver { 25 | 26 | private VolumeCallback callback; 27 | 28 | public VolumeReceiver(VolumeCallback cb) { 29 | callback = cb; 30 | } 31 | 32 | @Override 33 | public void onReceive(Context context, Intent intent) { 34 | if (intent.getAction().equals("android.media.VOLUME_CHANGED_ACTION") 35 | && callback != null) { 36 | Log.e(TAG, "android.media.VOLUME_CHANGED_ACTION"); 37 | callback.volumeChanged(); 38 | } 39 | } 40 | } 41 | 42 | public static BroadcastReceiver registerVolumeReceiver(Context context, VolumeCallback callback) { 43 | VolumeReceiver mVolumeReceiver = null; 44 | try { 45 | mVolumeReceiver = new VolumeReceiver(callback); 46 | IntentFilter filter = new IntentFilter(); 47 | filter.addAction("android.media.VOLUME_CHANGED_ACTION"); 48 | context.registerReceiver(mVolumeReceiver, filter); 49 | } catch (IllegalArgumentException ex1) { 50 | ex1.printStackTrace(); 51 | } catch (Exception ex2) { 52 | ex2.printStackTrace(); 53 | } 54 | return mVolumeReceiver; 55 | } 56 | 57 | public static void unRegisterVolumeReceiver(Context context, BroadcastReceiver receiver) { 58 | try { 59 | if (context != null && receiver != null) { 60 | context.unregisterReceiver(receiver); 61 | } 62 | } catch (IllegalArgumentException ex1) { 63 | ex1.printStackTrace(); 64 | } catch (Exception ex2) { 65 | ex2.printStackTrace(); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /android/src/main/jniLibs/arm64-v8a/libFaceSDK.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/jniLibs/arm64-v8a/libFaceSDK.so -------------------------------------------------------------------------------- /android/src/main/jniLibs/arm64-v8a/libbaidu_license.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/jniLibs/arm64-v8a/libbaidu_license.so -------------------------------------------------------------------------------- /android/src/main/jniLibs/armeabi-v7a/libFaceSDK.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/jniLibs/armeabi-v7a/libFaceSDK.so -------------------------------------------------------------------------------- /android/src/main/jniLibs/armeabi-v7a/libbaidu_license.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/jniLibs/armeabi-v7a/libbaidu_license.so -------------------------------------------------------------------------------- /android/src/main/jniLibs/x86/libFaceSDK.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/jniLibs/x86/libFaceSDK.so -------------------------------------------------------------------------------- /android/src/main/jniLibs/x86/libbaidu_license.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/jniLibs/x86/libbaidu_license.so -------------------------------------------------------------------------------- /android/src/main/res/drawable/bg_tips.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /android/src/main/res/drawable/bg_tips_no.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /android/src/main/res/layout/activity_face_detect.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 17 | 18 | 24 | 25 | 26 | 31 | 32 | 36 | 37 | 48 | 49 | 54 | 55 | 59 | 60 | 68 | 69 | 73 | 74 | 75 | 79 | 80 | 81 | 87 | 88 | 95 | 96 | 100 | 101 | 106 | 107 | -------------------------------------------------------------------------------- /android/src/main/res/layout/activity_face_detect_v3100.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 17 | 18 | 23 | 24 | 28 | 29 | 43 | 44 | 48 | 49 | 60 | 61 | 62 | 68 | 69 | 76 | 77 | 83 | 84 | 88 | 89 | 94 | 95 | -------------------------------------------------------------------------------- /android/src/main/res/layout/activity_face_liveness.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 17 | 18 | 24 | 25 | 26 | 31 | 32 | 36 | 37 | 48 | 49 | 54 | 55 | 59 | 60 | 68 | 69 | 73 | 74 | 75 | 79 | 80 | 81 | 87 | 88 | 95 | 96 | 100 | 101 | 106 | 107 | -------------------------------------------------------------------------------- /android/src/main/res/layout/activity_face_liveness_v3100.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 17 | 18 | 23 | 24 | 28 | 29 | 43 | 44 | 48 | 49 | 60 | 61 | 62 | 68 | 69 | 76 | 77 | 83 | 84 | 88 | 89 | 94 | 95 | -------------------------------------------------------------------------------- /android/src/main/res/layout/widget_face_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 31 | 32 | 36 | 37 | 47 | -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xhdpi/bg_face_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/mipmap-xhdpi/bg_face_round.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xhdpi/ic_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/mipmap-xhdpi/ic_close.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xhdpi/ic_disable_sound.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/mipmap-xhdpi/ic_disable_sound.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xhdpi/ic_enable_sound.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/mipmap-xhdpi/ic_enable_sound.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xxhdpi/ic_close_ext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/mipmap-xxhdpi/ic_close_ext.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xxhdpi/ic_disable_sound_ext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/mipmap-xxhdpi/ic_disable_sound_ext.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xxhdpi/ic_enable_sound_ext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/mipmap-xxhdpi/ic_enable_sound_ext.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xxhdpi/ic_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/mipmap-xxhdpi/ic_success.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xxhdpi/ic_warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/mipmap-xxhdpi/ic_warning.png -------------------------------------------------------------------------------- /android/src/main/res/raw/detect_face_in.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/raw/detect_face_in.mp3 -------------------------------------------------------------------------------- /android/src/main/res/raw/face_good.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/raw/face_good.mp3 -------------------------------------------------------------------------------- /android/src/main/res/raw/liveness_eye.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/raw/liveness_eye.mp3 -------------------------------------------------------------------------------- /android/src/main/res/raw/liveness_head_down.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/raw/liveness_head_down.mp3 -------------------------------------------------------------------------------- /android/src/main/res/raw/liveness_head_left.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/raw/liveness_head_left.mp3 -------------------------------------------------------------------------------- /android/src/main/res/raw/liveness_head_left_right.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/raw/liveness_head_left_right.mp3 -------------------------------------------------------------------------------- /android/src/main/res/raw/liveness_head_right.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/raw/liveness_head_right.mp3 -------------------------------------------------------------------------------- /android/src/main/res/raw/liveness_head_up.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/raw/liveness_head_up.mp3 -------------------------------------------------------------------------------- /android/src/main/res/raw/liveness_mouth.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/android/src/main/res/raw/liveness_mouth.mp3 -------------------------------------------------------------------------------- /android/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | #2F2F33 3 | #FFFFFF 4 | #FFA800 5 | -------------------------------------------------------------------------------- /android/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Baidu-IDL-FaceSDK 3 | 未检测到人脸 4 | 把脸移入框内 5 | 手机拿近一点 6 | 手机拿远一点 7 | 建议略微抬头 8 | 建议略微低头 9 | 建议略微向左转头 10 | 建议略微向右转头 11 | 脸部有遮挡 12 | 光线再亮些 13 | 请保持不动 14 | 请正对手机 15 | 检测超时 16 | 眨眨眼 17 | 请眨眨左边眼睛 18 | 请眨眨右边眼睛 19 | 张张嘴 20 | 向左缓慢转头 21 | 向右缓慢转头 22 | 摇摇头 23 | 缓慢抬头 24 | 缓慢低头 25 | 非常好 26 | 27 | -------------------------------------------------------------------------------- /android/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 17 | 18 | 29 | 30 | 41 | 42 | -------------------------------------------------------------------------------- /baidu_face_plugin.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /doc/license-apply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/doc/license-apply.png -------------------------------------------------------------------------------- /doc/license-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/doc/license-config.png -------------------------------------------------------------------------------- /doc/license-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/doc/license-demo.png -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | /build/ 32 | 33 | # Web related 34 | lib/generated_plugin_registrant.dart 35 | 36 | # Symbolication related 37 | app.*.symbols 38 | 39 | # Obfuscation related 40 | app.*.map.json 41 | 42 | # Exceptions to above rules. 43 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 44 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: e6b34c2b5c96bb95325269a29a84e83ed8909b5f 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # baidu_face_plugin_example 2 | 3 | Demonstrates how to use the baidu_face_plugin plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new FileNotFoundException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 28 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | applicationId "com.example.baidu_face_plugin.baidu_face_plugin_example" 36 | minSdkVersion 16 37 | targetSdkVersion 28 38 | versionCode flutterVersionCode.toInteger() 39 | versionName flutterVersionName 40 | } 41 | 42 | signingConfigs { 43 | 44 | def password = "10101100" 45 | def alias = "nutella" 46 | def filePath = "/Users/yuanchongyu/nutella.jks" //如 ../facesharp.jks//签名文件路径 47 | 48 | debug { 49 | keyAlias alias 50 | keyPassword password 51 | storeFile file(filePath) 52 | storePassword(password) 53 | } 54 | release { 55 | keyAlias alias 56 | keyPassword password 57 | storeFile file(filePath) 58 | storePassword(password) 59 | } 60 | } 61 | 62 | } 63 | 64 | flutter { 65 | source '../..' 66 | } 67 | -------------------------------------------------------------------------------- /example/android/app/debug/app-debug.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/android/app/debug/app-debug.apk -------------------------------------------------------------------------------- /example/android/app/debug/output.json: -------------------------------------------------------------------------------- 1 | [{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-debug.apk","fullName":"debug","baseName":"debug"},"path":"app-debug.apk","properties":{}}] -------------------------------------------------------------------------------- /example/android/app/profile/app-profile.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/android/app/profile/app-profile.apk -------------------------------------------------------------------------------- /example/android/app/profile/output.json: -------------------------------------------------------------------------------- 1 | [{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-profile.apk","fullName":"profile","baseName":"profile"},"path":"app-profile.apk","properties":{}}] -------------------------------------------------------------------------------- /example/android/app/release/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/android/app/release/app-release.apk -------------------------------------------------------------------------------- /example/android/app/release/output.json: -------------------------------------------------------------------------------- 1 | [{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 9 | 14 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 34 | 35 | 41 | 42 | 44 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /example/android/app/src/main/assets/idl-license.face-android: -------------------------------------------------------------------------------- 1 | 4978EAE9A19D8D91AEF9C594FC59484AF55981642C5F6FC8442125BBC6D1779E5E3BD468B318D8DCB16362A33703CB7BD28A51EBBE44F12DDA76C88F7BE636BF4C3DD5B24A4CC3E520AB63512CA679A85A85545E2B47859A38C1500267451EA59CECC7CD1634BB2178D35B84F93AAB449D8FFE20D4E3BF2D53090CB7CDCB01D1AA8492C5963F52622D85CE8BE42D70221B0FAC05581D162D6CC11B1E53ED893B549EC90B1B05E3BFAB3BB862A80D1C4594C146B0DD834C8BEABD46A9FF1418F4FB71AC37A923547F51C84315C30ABD33B226541218ECAA6F187781A0DFE34EF8BF21AF740C0C4861CF69F6274A361E1D71FB38A5C07FABEC074B028C59F5D14F 2 | 4A41958F14B2EAB75EFA217CD892A60B06953F6E750FCA5A4ED953DC6266C729598BB6BA0DC4CBA39DC230AAD30320D88B74C3A970399E63A723B8DE3F210BC2681D7709D81CCB869AEAAA5CF784DA7A5473C6BDD31D9B25A84EE20892F67427449CF7C8DF166D8B9C1921E1D7F02B241D2ED650AAF8F3CE542F0F50926E7090C4DE03550EBBCCDB53472F13653D4EFCF76CE73F76D98399CAD41D375BD09D7E986560AEDC7FD63C24F78AE74D362C8BD71420028518959209E045BF4AD657AA648D082933E969420D2EB9B174EE9AD1F19898CF9FDF675C5620C4C5E91D51F095D50947651CE1D7A2BF300D4DE3D684B320B85E9397E9D7990D9BD173E00630 3 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/baidu_face_plugin/baidu_face_plugin_example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.baidu_face_plugin.baidu_face_plugin_example; 2 | 3 | import android.Manifest; 4 | import android.annotation.TargetApi; 5 | import android.content.pm.PackageManager; 6 | import android.os.Build; 7 | import android.os.Bundle; 8 | 9 | import androidx.annotation.NonNull; 10 | import androidx.annotation.Nullable; 11 | 12 | import io.flutter.embedding.android.FlutterActivity; 13 | import io.flutter.embedding.engine.FlutterEngine; 14 | import io.flutter.plugins.GeneratedPluginRegistrant; 15 | 16 | public class MainActivity extends FlutterActivity { 17 | @Override 18 | public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { 19 | GeneratedPluginRegistrant.registerWith(flutterEngine); 20 | } 21 | 22 | // 以下几个方法为了获取权限,如果已用flutter实现,可以去掉 23 | @Override 24 | protected void onCreate(@Nullable Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | 27 | requestPermissions(99, Manifest.permission.CAMERA); 28 | } 29 | 30 | @TargetApi(Build.VERSION_CODES.M) 31 | @Override 32 | public void onRequestPermissionsResult(int requestCode, String[] permissions, 33 | int[] grantResults) { 34 | boolean flag = false; 35 | for (int i = 0; i < permissions.length; i++) { 36 | if (PackageManager.PERMISSION_GRANTED == grantResults[i]) { 37 | flag = true; 38 | } 39 | } 40 | if (!flag) { 41 | requestPermissions(99, Manifest.permission.CAMERA); 42 | } 43 | } 44 | 45 | public void requestPermissions(int requestCode, String permission) { 46 | if (permission != null && permission.length() > 0) { 47 | try { 48 | if (Build.VERSION.SDK_INT >= 23) { 49 | // 检查是否有权限 50 | int hasPer = checkSelfPermission(permission); 51 | if (hasPer != PackageManager.PERMISSION_GRANTED) { 52 | // 是否应该显示权限请求 53 | boolean isShould = shouldShowRequestPermissionRationale(permission); 54 | requestPermissions(new String[]{permission}, requestCode); 55 | } 56 | } else { 57 | 58 | } 59 | } catch (Exception ex) { 60 | ex.printStackTrace(); 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/baidu_face_plugin/baidu_face_plugin_example/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.baidu_face_plugin.baidu_face_plugin_example; 2 | 3 | import com.baidu.idl.face.platform.FaceConfig; 4 | import com.baidu.idl.face.platform.FaceEnvironment; 5 | import com.baidu.idl.face.platform.FaceSDKManager; 6 | import com.baidu.idl.face.platform.FaceStatusEnum; 7 | import com.baidu.idl.face.platform.LivenessTypeEnum; 8 | import com.example.baidu_face_plugin.baidu_face_plugin.Config; 9 | import com.example.baidu_face_plugin.baidu_face_plugin.FaceSDKResSettings; 10 | 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | import io.flutter.app.FlutterApplication; 15 | 16 | public class MainApplication extends FlutterApplication { 17 | @Override 18 | public void onCreate() { 19 | super.onCreate(); 20 | initFacePlugin(); 21 | } 22 | 23 | private void initFacePlugin() { 24 | // 初始化SDK 25 | FaceSDKManager.getInstance().initialize(this, "baidu-face-plugin-face-android", "idl-license.face-android"); 26 | 27 | // 随机动作 28 | Config.isLivenessRandom = true; 29 | // 根据需求添加活体动作 30 | Config.livenessList.clear(); 31 | Config.livenessList.add(LivenessTypeEnum.Eye); 32 | // TODO test 33 | // Config.livenessList.add(LivenessTypeEnum.Mouth); 34 | // Config.livenessList.add(LivenessTypeEnum.HeadUp); 35 | // Config.livenessList.add(LivenessTypeEnum.HeadDown); 36 | // Config.livenessList.add(LivenessTypeEnum.HeadLeft); 37 | // Config.livenessList.add(LivenessTypeEnum.HeadRight); 38 | // Config.livenessList.add(LivenessTypeEnum.HeadLeftOrRight); 39 | 40 | // 设置 FaceConfig 41 | FaceConfig config = FaceSDKManager.getInstance().getFaceConfig(); 42 | config.setLivenessTypeList(Config.livenessList); 43 | config.setLivenessRandom(Config.isLivenessRandom); 44 | config.setBlurnessValue(FaceEnvironment.VALUE_BLURNESS); 45 | config.setBrightnessValue(FaceEnvironment.VALUE_BRIGHTNESS); 46 | config.setCropFaceValue(FaceEnvironment.VALUE_CROP_FACE_SIZE); 47 | config.setHeadPitchValue(FaceEnvironment.VALUE_HEAD_PITCH); 48 | config.setHeadRollValue(FaceEnvironment.VALUE_HEAD_ROLL); 49 | config.setHeadYawValue(FaceEnvironment.VALUE_HEAD_YAW); 50 | config.setMinFaceSize(FaceEnvironment.VALUE_MIN_FACE_SIZE); 51 | config.setNotFaceValue(FaceEnvironment.VALUE_NOT_FACE_THRESHOLD); 52 | config.setOcclusionValue(FaceEnvironment.VALUE_OCCLUSION); 53 | config.setCheckFaceQuality(true); 54 | config.setFaceDecodeNumberOfThreads(2); 55 | // 关闭提示音 56 | config.setSound(false); 57 | FaceSDKManager.getInstance().setFaceConfig(config); 58 | 59 | // 初始化资源文件 60 | initResMap(); 61 | } 62 | 63 | private void initResMap() { 64 | Map> soundMap = new HashMap<>(); 65 | Map> tipsMap = new HashMap<>(); 66 | 67 | // language 多语言 68 | Map zhSoundMap = new HashMap<>(); 69 | zhSoundMap.put(FaceStatusEnum.Detect_NoFace, com.example.baidu_face_plugin.baidu_face_plugin.R.raw.detect_face_in); 70 | zhSoundMap.put(FaceStatusEnum.Detect_FacePointOut, com.example.baidu_face_plugin.baidu_face_plugin.R.raw.detect_face_in); 71 | zhSoundMap.put(FaceStatusEnum.Liveness_Eye, com.example.baidu_face_plugin.baidu_face_plugin.R.raw.liveness_eye); 72 | zhSoundMap.put(FaceStatusEnum.Liveness_Mouth, com.example.baidu_face_plugin.baidu_face_plugin.R.raw.liveness_mouth); 73 | zhSoundMap.put(FaceStatusEnum.Liveness_HeadUp, com.example.baidu_face_plugin.baidu_face_plugin.R.raw.liveness_head_up); 74 | zhSoundMap.put(FaceStatusEnum.Liveness_HeadDown, com.example.baidu_face_plugin.baidu_face_plugin.R.raw.liveness_head_down); 75 | zhSoundMap.put(FaceStatusEnum.Liveness_HeadLeft, com.example.baidu_face_plugin.baidu_face_plugin.R.raw.liveness_head_left); 76 | zhSoundMap.put(FaceStatusEnum.Liveness_HeadRight, com.example.baidu_face_plugin.baidu_face_plugin.R.raw.liveness_head_right); 77 | zhSoundMap.put(FaceStatusEnum.Liveness_HeadLeftRight, com.example.baidu_face_plugin.baidu_face_plugin.R.raw.liveness_head_left_right); 78 | zhSoundMap.put(FaceStatusEnum.Liveness_OK, com.example.baidu_face_plugin.baidu_face_plugin.R.raw.face_good); 79 | zhSoundMap.put(FaceStatusEnum.OK, com.example.baidu_face_plugin.baidu_face_plugin.R.raw.face_good); 80 | soundMap.put("zh", zhSoundMap); 81 | 82 | Map zhTipsMap = new HashMap<>(); 83 | zhTipsMap.put(FaceStatusEnum.Detect_NoFace, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_no_face); 84 | zhTipsMap.put(FaceStatusEnum.Detect_FacePointOut, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_face_in); 85 | zhTipsMap.put(FaceStatusEnum.Detect_PoorIllumintion, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_low_light); 86 | zhTipsMap.put(FaceStatusEnum.Detect_ImageBlured, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_keep); 87 | zhTipsMap.put(FaceStatusEnum.Detect_OccLeftEye, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_occ_face); 88 | zhTipsMap.put(FaceStatusEnum.Detect_OccRightEye, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_occ_face); 89 | zhTipsMap.put(FaceStatusEnum.Detect_OccNose, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_occ_face); 90 | zhTipsMap.put(FaceStatusEnum.Detect_OccMouth, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_occ_face); 91 | zhTipsMap.put(FaceStatusEnum.Detect_OccLeftContour, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_occ_face); 92 | zhTipsMap.put(FaceStatusEnum.Detect_OccRightContour, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_occ_face); 93 | zhTipsMap.put(FaceStatusEnum.Detect_OccChin, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_occ_face); 94 | zhTipsMap.put(FaceStatusEnum.Detect_PitchOutOfUpMaxRange, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_head_down); 95 | zhTipsMap.put(FaceStatusEnum.Detect_PitchOutOfDownMaxRange, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_head_up); 96 | zhTipsMap.put(FaceStatusEnum.Detect_PitchOutOfLeftMaxRange, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_head_right); 97 | zhTipsMap.put(FaceStatusEnum.Detect_PitchOutOfRightMaxRange, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_head_left); 98 | zhTipsMap.put(FaceStatusEnum.Detect_FaceZoomIn, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_zoom_in); 99 | zhTipsMap.put(FaceStatusEnum.Detect_FaceZoomOut, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_zoom_out); 100 | 101 | zhTipsMap.put(FaceStatusEnum.Liveness_Eye, com.example.baidu_face_plugin.baidu_face_plugin.R.string.liveness_eye); 102 | zhTipsMap.put(FaceStatusEnum.Liveness_Mouth, com.example.baidu_face_plugin.baidu_face_plugin.R.string.liveness_mouth); 103 | zhTipsMap.put(FaceStatusEnum.Liveness_HeadUp, com.example.baidu_face_plugin.baidu_face_plugin.R.string.liveness_head_up); 104 | zhTipsMap.put(FaceStatusEnum.Liveness_HeadDown, com.example.baidu_face_plugin.baidu_face_plugin.R.string.liveness_head_down); 105 | zhTipsMap.put(FaceStatusEnum.Liveness_HeadLeft, com.example.baidu_face_plugin.baidu_face_plugin.R.string.liveness_head_left); 106 | zhTipsMap.put(FaceStatusEnum.Liveness_HeadRight, com.example.baidu_face_plugin.baidu_face_plugin.R.string.liveness_head_right); 107 | zhTipsMap.put(FaceStatusEnum.Liveness_HeadLeftRight, com.example.baidu_face_plugin.baidu_face_plugin.R.string.liveness_head_left_right); 108 | zhTipsMap.put(FaceStatusEnum.Liveness_OK, com.example.baidu_face_plugin.baidu_face_plugin.R.string.liveness_good); 109 | zhTipsMap.put(FaceStatusEnum.OK, com.example.baidu_face_plugin.baidu_face_plugin.R.string.liveness_good); 110 | 111 | zhTipsMap.put(FaceStatusEnum.Error_Timeout, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_timeout); 112 | zhTipsMap.put(FaceStatusEnum.Error_DetectTimeout, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_timeout); 113 | zhTipsMap.put(FaceStatusEnum.Error_LivenessTimeout, com.example.baidu_face_plugin.baidu_face_plugin.R.string.detect_timeout); 114 | tipsMap.put("zh", zhTipsMap); 115 | 116 | 117 | FaceSDKResSettings.initResMaps(soundMap, tipsMap); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.6.3' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | generated_key_values = {} 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) do |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | generated_key_values[podname] = podpath 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | end 32 | generated_key_values 33 | end 34 | 35 | target 'Runner' do 36 | use_frameworks! 37 | use_modular_headers! 38 | 39 | # Flutter Pod 40 | 41 | copied_flutter_dir = File.join(__dir__, 'Flutter') 42 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') 43 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') 44 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) 45 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. 46 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. 47 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. 48 | 49 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') 50 | unless File.exist?(generated_xcode_build_settings_path) 51 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" 52 | end 53 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) 54 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; 55 | 56 | unless File.exist?(copied_framework_path) 57 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) 58 | end 59 | unless File.exist?(copied_podspec_path) 60 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) 61 | end 62 | end 63 | 64 | # Keep pod path relative so it can be checked into Podfile.lock. 65 | pod 'Flutter', :path => 'Flutter' 66 | 67 | # Plugin Pods 68 | 69 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 70 | # referring to absolute paths on developers' machines. 71 | system('rm -rf .symlinks') 72 | system('mkdir -p .symlinks/plugins') 73 | plugin_pods = parse_KV_file('../.flutter-plugins') 74 | plugin_pods.each do |name, path| 75 | symlink = File.join('.symlinks', 'plugins', name) 76 | File.symlink(path, symlink) 77 | pod name, :path => File.join(symlink, 'ios') 78 | end 79 | end 80 | 81 | post_install do |installer| 82 | installer.pods_project.targets.each do |target| 83 | target.build_configurations.each do |config| 84 | config.build_settings['ENABLE_BITCODE'] = 'NO' 85 | end 86 | end 87 | end 88 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | baidu_face_plugin_example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:baidu_face_plugin/baidu_face_plugin.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:fluttertoast/fluttertoast.dart'; 6 | 7 | Future main() async { 8 | runApp(MyApp()); 9 | } 10 | 11 | class MyApp extends StatefulWidget { 12 | @override 13 | _MyAppState createState() => _MyAppState(); 14 | } 15 | 16 | class _MyAppState extends State { 17 | @override 18 | Widget build(BuildContext context) { 19 | return MaterialApp( 20 | home: Scaffold( 21 | appBar: AppBar( 22 | title: const Text('Plugin example app'), 23 | ), 24 | body: Column( 25 | mainAxisAlignment: MainAxisAlignment.center, 26 | crossAxisAlignment: CrossAxisAlignment.center, 27 | children: [ 28 | RaisedButton( 29 | child: Text("打开liveness"), 30 | onPressed: () { 31 | _liveness(); 32 | }), 33 | RaisedButton( 34 | child: Text("打开detect"), 35 | onPressed: () { 36 | _detect(); 37 | }), 38 | ], 39 | )), 40 | ); 41 | } 42 | 43 | _liveness() async { 44 | LivenessResult result = await new BaiduFacePlugin().liveness(); 45 | 46 | debugPrint('LivenessResult: $result'); 47 | Fluttertoast.showToast(msg: result.toString(), timeInSecForIosWeb: 4); 48 | 49 | // setState 50 | } 51 | 52 | _detect() async { 53 | DetectResult result = await new BaiduFacePlugin().detect(); 54 | 55 | debugPrint('DetectResult: $result'); 56 | Fluttertoast.showToast(msg: result.toString(), timeInSecForIosWeb: 4); 57 | 58 | // setState 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | archive: 5 | dependency: transitive 6 | description: 7 | name: archive 8 | url: "https://pub.flutter-io.cn" 9 | source: hosted 10 | version: "2.0.13" 11 | args: 12 | dependency: transitive 13 | description: 14 | name: args 15 | url: "https://pub.flutter-io.cn" 16 | source: hosted 17 | version: "1.6.0" 18 | async: 19 | dependency: transitive 20 | description: 21 | name: async 22 | url: "https://pub.flutter-io.cn" 23 | source: hosted 24 | version: "2.4.1" 25 | baidu_face_plugin: 26 | dependency: "direct main" 27 | description: 28 | path: ".." 29 | relative: true 30 | source: path 31 | version: "0.0.1" 32 | boolean_selector: 33 | dependency: transitive 34 | description: 35 | name: boolean_selector 36 | url: "https://pub.flutter-io.cn" 37 | source: hosted 38 | version: "2.0.0" 39 | charcode: 40 | dependency: transitive 41 | description: 42 | name: charcode 43 | url: "https://pub.flutter-io.cn" 44 | source: hosted 45 | version: "1.1.3" 46 | collection: 47 | dependency: transitive 48 | description: 49 | name: collection 50 | url: "https://pub.flutter-io.cn" 51 | source: hosted 52 | version: "1.14.12" 53 | convert: 54 | dependency: transitive 55 | description: 56 | name: convert 57 | url: "https://pub.flutter-io.cn" 58 | source: hosted 59 | version: "2.1.1" 60 | crypto: 61 | dependency: transitive 62 | description: 63 | name: crypto 64 | url: "https://pub.flutter-io.cn" 65 | source: hosted 66 | version: "2.1.4" 67 | cupertino_icons: 68 | dependency: "direct main" 69 | description: 70 | name: cupertino_icons 71 | url: "https://pub.flutter-io.cn" 72 | source: hosted 73 | version: "0.1.3" 74 | flutter: 75 | dependency: "direct main" 76 | description: flutter 77 | source: sdk 78 | version: "0.0.0" 79 | flutter_test: 80 | dependency: "direct dev" 81 | description: flutter 82 | source: sdk 83 | version: "0.0.0" 84 | flutter_web_plugins: 85 | dependency: transitive 86 | description: flutter 87 | source: sdk 88 | version: "0.0.0" 89 | fluttertoast: 90 | dependency: "direct main" 91 | description: 92 | name: fluttertoast 93 | url: "https://pub.flutter-io.cn" 94 | source: hosted 95 | version: "4.0.1" 96 | image: 97 | dependency: transitive 98 | description: 99 | name: image 100 | url: "https://pub.flutter-io.cn" 101 | source: hosted 102 | version: "2.1.12" 103 | matcher: 104 | dependency: transitive 105 | description: 106 | name: matcher 107 | url: "https://pub.flutter-io.cn" 108 | source: hosted 109 | version: "0.12.6" 110 | meta: 111 | dependency: transitive 112 | description: 113 | name: meta 114 | url: "https://pub.flutter-io.cn" 115 | source: hosted 116 | version: "1.1.8" 117 | path: 118 | dependency: transitive 119 | description: 120 | name: path 121 | url: "https://pub.flutter-io.cn" 122 | source: hosted 123 | version: "1.6.4" 124 | petitparser: 125 | dependency: transitive 126 | description: 127 | name: petitparser 128 | url: "https://pub.flutter-io.cn" 129 | source: hosted 130 | version: "2.4.0" 131 | quiver: 132 | dependency: transitive 133 | description: 134 | name: quiver 135 | url: "https://pub.flutter-io.cn" 136 | source: hosted 137 | version: "2.1.3" 138 | sky_engine: 139 | dependency: transitive 140 | description: flutter 141 | source: sdk 142 | version: "0.0.99" 143 | source_span: 144 | dependency: transitive 145 | description: 146 | name: source_span 147 | url: "https://pub.flutter-io.cn" 148 | source: hosted 149 | version: "1.7.0" 150 | stack_trace: 151 | dependency: transitive 152 | description: 153 | name: stack_trace 154 | url: "https://pub.flutter-io.cn" 155 | source: hosted 156 | version: "1.9.3" 157 | stream_channel: 158 | dependency: transitive 159 | description: 160 | name: stream_channel 161 | url: "https://pub.flutter-io.cn" 162 | source: hosted 163 | version: "2.0.0" 164 | string_scanner: 165 | dependency: transitive 166 | description: 167 | name: string_scanner 168 | url: "https://pub.flutter-io.cn" 169 | source: hosted 170 | version: "1.0.5" 171 | term_glyph: 172 | dependency: transitive 173 | description: 174 | name: term_glyph 175 | url: "https://pub.flutter-io.cn" 176 | source: hosted 177 | version: "1.1.0" 178 | test_api: 179 | dependency: transitive 180 | description: 181 | name: test_api 182 | url: "https://pub.flutter-io.cn" 183 | source: hosted 184 | version: "0.2.15" 185 | typed_data: 186 | dependency: transitive 187 | description: 188 | name: typed_data 189 | url: "https://pub.flutter-io.cn" 190 | source: hosted 191 | version: "1.1.6" 192 | vector_math: 193 | dependency: transitive 194 | description: 195 | name: vector_math 196 | url: "https://pub.flutter-io.cn" 197 | source: hosted 198 | version: "2.0.8" 199 | xml: 200 | dependency: transitive 201 | description: 202 | name: xml 203 | url: "https://pub.flutter-io.cn" 204 | source: hosted 205 | version: "3.6.1" 206 | sdks: 207 | dart: ">=2.7.0 <3.0.0" 208 | flutter: ">=1.12.8 <2.0.0" 209 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: baidu_face_plugin_example 2 | description: Demonstrates how to use the baidu_face_plugin plugin. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | environment: 9 | sdk: ">=2.7.0 <3.0.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | 15 | baidu_face_plugin: 16 | # When depending on this package from a real application you should use: 17 | # baidu_face_plugin: ^x.y.z 18 | # See https://dart.dev/tools/pub/dependencies#version-constraints 19 | # The example app is bundled with the plugin so we use a path dependency on 20 | # the parent directory to use the current plugin's version. 21 | path: ../ 22 | 23 | # The following adds the Cupertino Icons font to your application. 24 | # Use with the CupertinoIcons class for iOS style icons. 25 | cupertino_icons: ^0.1.3 26 | 27 | fluttertoast: ^4.0.1 28 | 29 | dev_dependencies: 30 | flutter_test: 31 | sdk: flutter 32 | 33 | # For information on the generic Dart part of this file, see the 34 | # following page: https://dart.dev/tools/pub/pubspec 35 | 36 | # The following section is specific to Flutter. 37 | flutter: 38 | 39 | # The following line ensures that the Material Icons font is 40 | # included with your application, so that you can use the icons in 41 | # the material Icons class. 42 | uses-material-design: true 43 | 44 | # To add assets to your application, add an assets section, like this: 45 | # assets: 46 | # - images/a_dot_burr.jpeg 47 | # - images/a_dot_ham.jpeg 48 | 49 | # An image asset can refer to one or more resolution-specific "variants", see 50 | # https://flutter.dev/assets-and-images/#resolution-aware. 51 | 52 | # For details regarding adding assets from package dependencies, see 53 | # https://flutter.dev/assets-and-images/#from-packages 54 | 55 | # To add custom fonts to your application, add a fonts section here, 56 | # in this "flutter" section. Each entry in this list should have a 57 | # "family" key with the font family name, and a "fonts" key with a 58 | # list giving the asset and other descriptors for the font. For 59 | # example: 60 | # fonts: 61 | # - family: Schyler 62 | # fonts: 63 | # - asset: fonts/Schyler-Regular.ttf 64 | # - asset: fonts/Schyler-Italic.ttf 65 | # style: italic 66 | # - family: Trajan Pro 67 | # fonts: 68 | # - asset: fonts/TrajanPro.ttf 69 | # - asset: fonts/TrajanPro_Bold.ttf 70 | # weight: 700 71 | # 72 | # For details regarding fonts from package dependencies, 73 | # see https://flutter.dev/custom-fonts/#from-packages 74 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:baidu_face_plugin_example/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Verify Platform version', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that platform version is retrieved. 19 | expect( 20 | find.byWidgetPredicate( 21 | (Widget widget) => widget is Text && 22 | widget.data.startsWith('Running on:'), 23 | ), 24 | findsOneWidget, 25 | ); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nnnggel/baidu_face_plugin/0946e919c1bce9375d873aa08e3a86132b33d174/ios/Assets/.gitkeep -------------------------------------------------------------------------------- /ios/Classes/BaiduFacePlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface BaiduFacePlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /ios/Classes/BaiduFacePlugin.m: -------------------------------------------------------------------------------- 1 | #import "BaiduFacePlugin.h" 2 | #if __has_include() 3 | #import 4 | #else 5 | // Support project import fallback if the generated compatibility header 6 | // is not copied when this plugin is created as a library. 7 | // https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 8 | #import "baidu_face_plugin-Swift.h" 9 | #endif 10 | 11 | @implementation BaiduFacePlugin 12 | + (void)registerWithRegistrar:(NSObject*)registrar { 13 | [SwiftBaiduFacePlugin registerWithRegistrar:registrar]; 14 | } 15 | @end 16 | -------------------------------------------------------------------------------- /ios/Classes/SwiftBaiduFacePlugin.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | 4 | public class SwiftBaiduFacePlugin: NSObject, FlutterPlugin { 5 | public static func register(with registrar: FlutterPluginRegistrar) { 6 | let channel = FlutterMethodChannel(name: "baidu_face_plugin", binaryMessenger: registrar.messenger()) 7 | let instance = SwiftBaiduFacePlugin() 8 | registrar.addMethodCallDelegate(instance, channel: channel) 9 | } 10 | 11 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { 12 | result("iOS " + UIDevice.current.systemVersion) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ios/baidu_face_plugin.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint baidu_face_plugin.podspec' to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'baidu_face_plugin' 7 | s.version = '0.0.1' 8 | s.summary = 'A new Flutter project.' 9 | s.description = <<-DESC 10 | A new Flutter project. 11 | DESC 12 | s.homepage = 'http://example.com' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Your Company' => 'email@example.com' } 15 | s.source = { :path => '.' } 16 | s.source_files = 'Classes/**/*' 17 | s.dependency 'Flutter' 18 | s.platform = :ios, '8.0' 19 | 20 | # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. 21 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } 22 | s.swift_version = '5.0' 23 | end 24 | -------------------------------------------------------------------------------- /lib/baidu_face_plugin.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/services.dart'; 4 | 5 | class BaiduFacePlugin { 6 | static const MethodChannel _channel = 7 | const MethodChannel('com.example.baidu_face_plugin'); 8 | 9 | Future liveness({language = 'zh'}) async { 10 | var arguments = Map(); 11 | arguments['language'] = language; 12 | final Map map = 13 | await _channel.invokeMethod('liveness', arguments); 14 | return map != null ? new LivenessResult.fromMap(map) : null; 15 | } 16 | 17 | Future detect({language = 'zh'}) async { 18 | var arguments = Map(); 19 | arguments['language'] = language; 20 | final Map map = 21 | await _channel.invokeMethod('detect', arguments); 22 | return map != null ? new DetectResult.fromMap(map) : null; 23 | } 24 | } 25 | 26 | class LivenessResult { 27 | LivenessResult({this.success, this.image}); 28 | 29 | factory LivenessResult.fromMap(Map map) => 30 | new LivenessResult( 31 | success: map['success'], 32 | image: map['image'], 33 | ); 34 | 35 | final String success; 36 | 37 | // sucess=true 38 | final String image; 39 | 40 | @override 41 | String toString() => 'LivenessResult: $success,$image'; 42 | } 43 | 44 | class DetectResult { 45 | DetectResult({this.success, this.image}); 46 | 47 | factory DetectResult.fromMap(Map map) => new DetectResult( 48 | success: map['success'], 49 | image: map['image'], 50 | ); 51 | 52 | final String success; 53 | 54 | // sucess=true 55 | final String image; 56 | 57 | @override 58 | String toString() => 'DetectResult: $success,$image'; 59 | } 60 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | archive: 5 | dependency: transitive 6 | description: 7 | name: archive 8 | url: "https://pub.flutter-io.cn" 9 | source: hosted 10 | version: "2.0.13" 11 | args: 12 | dependency: transitive 13 | description: 14 | name: args 15 | url: "https://pub.flutter-io.cn" 16 | source: hosted 17 | version: "1.6.0" 18 | async: 19 | dependency: transitive 20 | description: 21 | name: async 22 | url: "https://pub.flutter-io.cn" 23 | source: hosted 24 | version: "2.4.1" 25 | boolean_selector: 26 | dependency: transitive 27 | description: 28 | name: boolean_selector 29 | url: "https://pub.flutter-io.cn" 30 | source: hosted 31 | version: "2.0.0" 32 | charcode: 33 | dependency: transitive 34 | description: 35 | name: charcode 36 | url: "https://pub.flutter-io.cn" 37 | source: hosted 38 | version: "1.1.3" 39 | collection: 40 | dependency: transitive 41 | description: 42 | name: collection 43 | url: "https://pub.flutter-io.cn" 44 | source: hosted 45 | version: "1.14.12" 46 | convert: 47 | dependency: transitive 48 | description: 49 | name: convert 50 | url: "https://pub.flutter-io.cn" 51 | source: hosted 52 | version: "2.1.1" 53 | crypto: 54 | dependency: transitive 55 | description: 56 | name: crypto 57 | url: "https://pub.flutter-io.cn" 58 | source: hosted 59 | version: "2.1.4" 60 | flutter: 61 | dependency: "direct main" 62 | description: flutter 63 | source: sdk 64 | version: "0.0.0" 65 | flutter_test: 66 | dependency: "direct dev" 67 | description: flutter 68 | source: sdk 69 | version: "0.0.0" 70 | image: 71 | dependency: transitive 72 | description: 73 | name: image 74 | url: "https://pub.flutter-io.cn" 75 | source: hosted 76 | version: "2.1.12" 77 | matcher: 78 | dependency: transitive 79 | description: 80 | name: matcher 81 | url: "https://pub.flutter-io.cn" 82 | source: hosted 83 | version: "0.12.6" 84 | meta: 85 | dependency: transitive 86 | description: 87 | name: meta 88 | url: "https://pub.flutter-io.cn" 89 | source: hosted 90 | version: "1.1.8" 91 | path: 92 | dependency: transitive 93 | description: 94 | name: path 95 | url: "https://pub.flutter-io.cn" 96 | source: hosted 97 | version: "1.6.4" 98 | petitparser: 99 | dependency: transitive 100 | description: 101 | name: petitparser 102 | url: "https://pub.flutter-io.cn" 103 | source: hosted 104 | version: "2.4.0" 105 | quiver: 106 | dependency: transitive 107 | description: 108 | name: quiver 109 | url: "https://pub.flutter-io.cn" 110 | source: hosted 111 | version: "2.1.3" 112 | sky_engine: 113 | dependency: transitive 114 | description: flutter 115 | source: sdk 116 | version: "0.0.99" 117 | source_span: 118 | dependency: transitive 119 | description: 120 | name: source_span 121 | url: "https://pub.flutter-io.cn" 122 | source: hosted 123 | version: "1.7.0" 124 | stack_trace: 125 | dependency: transitive 126 | description: 127 | name: stack_trace 128 | url: "https://pub.flutter-io.cn" 129 | source: hosted 130 | version: "1.9.3" 131 | stream_channel: 132 | dependency: transitive 133 | description: 134 | name: stream_channel 135 | url: "https://pub.flutter-io.cn" 136 | source: hosted 137 | version: "2.0.0" 138 | string_scanner: 139 | dependency: transitive 140 | description: 141 | name: string_scanner 142 | url: "https://pub.flutter-io.cn" 143 | source: hosted 144 | version: "1.0.5" 145 | term_glyph: 146 | dependency: transitive 147 | description: 148 | name: term_glyph 149 | url: "https://pub.flutter-io.cn" 150 | source: hosted 151 | version: "1.1.0" 152 | test_api: 153 | dependency: transitive 154 | description: 155 | name: test_api 156 | url: "https://pub.flutter-io.cn" 157 | source: hosted 158 | version: "0.2.15" 159 | typed_data: 160 | dependency: transitive 161 | description: 162 | name: typed_data 163 | url: "https://pub.flutter-io.cn" 164 | source: hosted 165 | version: "1.1.6" 166 | vector_math: 167 | dependency: transitive 168 | description: 169 | name: vector_math 170 | url: "https://pub.flutter-io.cn" 171 | source: hosted 172 | version: "2.0.8" 173 | xml: 174 | dependency: transitive 175 | description: 176 | name: xml 177 | url: "https://pub.flutter-io.cn" 178 | source: hosted 179 | version: "3.6.1" 180 | sdks: 181 | dart: ">=2.7.0 <3.0.0" 182 | flutter: ">=1.10.0" 183 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: baidu_face_plugin 2 | description: A Flutter plugin for baidu face recognization and liveness. 3 | version: 1.0.2 4 | homepage: https://github.com/nnnggel/baidu_face_plugin 5 | 6 | environment: 7 | sdk: ">=2.7.0 <3.0.0" 8 | flutter: ">=1.10.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | dev_dependencies: 15 | flutter_test: 16 | sdk: flutter 17 | 18 | # For information on the generic Dart part of this file, see the 19 | # following page: https://dart.dev/tools/pub/pubspec 20 | 21 | # The following section is specific to Flutter. 22 | flutter: 23 | # This section identifies this Flutter project as a plugin project. 24 | # The 'pluginClass' and Android 'package' identifiers should not ordinarily 25 | # be modified. They are used by the tooling to maintain consistency when 26 | # adding or updating assets for this project. 27 | plugin: 28 | platforms: 29 | android: 30 | package: com.example.baidu_face_plugin.baidu_face_plugin 31 | pluginClass: BaiduFacePlugin 32 | ios: 33 | pluginClass: BaiduFacePlugin 34 | 35 | # To add assets to your plugin package, add an assets section, like this: 36 | # assets: 37 | # - images/a_dot_burr.jpeg 38 | # - images/a_dot_ham.jpeg 39 | # 40 | # For details regarding assets in packages, see 41 | # https://flutter.dev/assets-and-images/#from-packages 42 | # 43 | # An image asset can refer to one or more resolution-specific "variants", see 44 | # https://flutter.dev/assets-and-images/#resolution-aware. 45 | 46 | # To add custom fonts to your plugin package, add a fonts section here, 47 | # in this "flutter" section. Each entry in this list should have a 48 | # "family" key with the font family name, and a "fonts" key with a 49 | # list giving the asset and other descriptors for the font. For 50 | # example: 51 | # fonts: 52 | # - family: Schyler 53 | # fonts: 54 | # - asset: fonts/Schyler-Regular.ttf 55 | # - asset: fonts/Schyler-Italic.ttf 56 | # style: italic 57 | # - family: Trajan Pro 58 | # fonts: 59 | # - asset: fonts/TrajanPro.ttf 60 | # - asset: fonts/TrajanPro_Bold.ttf 61 | # weight: 700 62 | # 63 | # For details regarding fonts in packages, see 64 | # https://flutter.dev/custom-fonts/#from-packages 65 | --------------------------------------------------------------------------------