├── .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 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/dictionaries:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
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 |
4 |
5 |
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 | 
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 | 
37 |
38 | > 步骤 2 和 3 中的配置可以在新建完授权后,可下载示例项目进行参考
39 | > 
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 |
--------------------------------------------------------------------------------