├── .gitignore
├── .idea
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── gradle.xml
├── libraries
│ ├── BmobSDK_3_5_3_20161116.xml
│ ├── FaceppSDK.xml
│ ├── Msc.xml
│ ├── android_android_24.xml
│ ├── animated_vector_drawable_24_2_1.xml
│ ├── appcompat_v7_24_2_1.xml
│ ├── constraint_layout_1_0_1.xml
│ ├── constraint_layout_solver_1_0_1.xml
│ ├── converter_gson_2_1_0.xml
│ ├── espresso_core_2_2_2.xml
│ ├── espresso_idling_resource_2_2_2.xml
│ ├── exposed_instrumentation_api_publish_0_5.xml
│ ├── eyekey_sdk_2_2.xml
│ ├── gson_2_7.xml
│ ├── hamcrest_core_1_3.xml
│ ├── hamcrest_integration_1_3.xml
│ ├── hamcrest_library_1_3.xml
│ ├── javawriter_2_1_1.xml
│ ├── javax_annotation_api_1_2.xml
│ ├── javax_inject_1.xml
│ ├── jsr305_2_0_1.xml
│ ├── junit_4_12.xml
│ ├── okhttp_3_4_1.xml
│ ├── okio_1_9_0.xml
│ ├── org_apache_http_legacy.xml
│ ├── org_apache_http_legacy_android_24.xml
│ ├── picasso_2_4_0.xml
│ ├── recyclerview_v7_24_2_1.xml
│ ├── retrofit_2_1_0.xml
│ ├── rules_0_5.xml
│ ├── runner_0_5.xml
│ ├── rxandroid_1_2_0.xml
│ ├── rxjava_1_1_6.xml
│ ├── support_annotations_24_2_1.xml
│ ├── support_compat_24_2_1.xml
│ ├── support_core_ui_24_2_1.xml
│ ├── support_core_utils_24_2_1.xml
│ ├── support_fragment_24_2_1.xml
│ ├── support_media_compat_24_2_1.xml
│ ├── support_v4_24_2_1.xml
│ └── support_vector_drawable_24_2_1.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── libs
│ ├── BmobSDK_3.5.3_20161116.jar
│ ├── FaceppSDK.jar
│ ├── Msc.jar
│ ├── arm64-v8a
│ │ ├── libBmobStat.so
│ │ ├── libbmob.so
│ │ └── libmsc.so
│ ├── armeabi-v7a
│ │ ├── libBmobStat.so
│ │ ├── libbmob.so
│ │ └── libmsc.so
│ ├── armeabi
│ │ ├── libBmobStat.so
│ │ ├── libbmob.so
│ │ └── libmsc.so
│ ├── converter-gson-2.1.0.jar
│ ├── eyekey-sdk_2.2.jar
│ ├── gson-2.7.jar
│ ├── mips
│ │ ├── libBmobStat.so
│ │ └── libbmob.so
│ ├── mips64
│ │ ├── libBmobStat.so
│ │ └── libbmob.so
│ ├── okhttp-3.4.1.jar
│ ├── okio-1.9.0.jar
│ ├── org.apache.http.legacy.jar
│ ├── picasso-2.4.0.jar
│ ├── retrofit-2.1.0.jar
│ ├── rxandroid-1.2.0.jar
│ ├── rxjava-1.1.6.jar
│ ├── x86
│ │ ├── libBmobStat.so
│ │ └── libbmob.so
│ └── x86_64
│ │ ├── libBmobStat.so
│ │ └── libbmob.so
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── henu
│ │ └── swface
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ ├── com
│ │ │ └── henu
│ │ │ │ └── swface
│ │ │ │ ├── Adapter
│ │ │ │ ├── FaceDetailAdapter.java
│ │ │ │ ├── ManageAdapter.java
│ │ │ │ └── StickyListAdapter.java
│ │ │ │ ├── Database
│ │ │ │ ├── BmobDataHelper.java
│ │ │ │ ├── DatabaseAdapter.java
│ │ │ │ ├── DatabaseHelper.java
│ │ │ │ ├── FaceMetaData.java
│ │ │ │ ├── SignLogData.java
│ │ │ │ └── UserMetaData.java
│ │ │ │ ├── MyApplication.java
│ │ │ │ ├── Utils
│ │ │ │ ├── DateUtil.java
│ │ │ │ ├── FaceRect.java
│ │ │ │ ├── FaceSetUtil.java
│ │ │ │ ├── FaceUtil.java
│ │ │ │ ├── FinalUtil.java
│ │ │ │ ├── JSONUtil.java
│ │ │ │ ├── ParseResult.java
│ │ │ │ ├── PictureUtil.java
│ │ │ │ └── RoundTransform.java
│ │ │ │ ├── VO
│ │ │ │ ├── Face.java
│ │ │ │ ├── FaceSignIn.java
│ │ │ │ ├── SignLog.java
│ │ │ │ ├── UserHasSigned.java
│ │ │ │ └── UserLogin.java
│ │ │ │ └── activity
│ │ │ │ ├── AddFaceActivity.java
│ │ │ │ ├── BaseVideoActivity.java
│ │ │ │ ├── DialogInputNameActivity.java
│ │ │ │ ├── FaceDetailActivity.java
│ │ │ │ ├── LoginActivity.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── ManageActivity.java
│ │ │ │ ├── RegisterFaceActivity.java
│ │ │ │ ├── SignInActivity.java
│ │ │ │ ├── SignLogActivity.java
│ │ │ │ └── ViewPictureActivity.java
│ │ ├── in
│ │ │ └── srain
│ │ │ │ └── cube
│ │ │ │ └── views
│ │ │ │ └── ptr
│ │ │ │ ├── PtrClassicDefaultHeader.java
│ │ │ │ ├── PtrClassicFrameLayout.java
│ │ │ │ ├── PtrDefaultHandler.java
│ │ │ │ ├── PtrFrameLayout.java
│ │ │ │ ├── PtrHandler.java
│ │ │ │ ├── PtrUIHandler.java
│ │ │ │ ├── PtrUIHandlerHolder.java
│ │ │ │ ├── PtrUIHandlerHook.java
│ │ │ │ ├── header
│ │ │ │ ├── MaterialHeader.java
│ │ │ │ ├── MaterialProgressDrawable.java
│ │ │ │ ├── StoreHouseBarItem.java
│ │ │ │ ├── StoreHouseHeader.java
│ │ │ │ └── StoreHousePath.java
│ │ │ │ ├── indicator
│ │ │ │ ├── PtrIndicator.java
│ │ │ │ └── PtrTensionIndicator.java
│ │ │ │ └── util
│ │ │ │ ├── PtrCLog.java
│ │ │ │ └── PtrLocalDisplay.java
│ │ └── se
│ │ │ └── emilsjolander
│ │ │ └── stickylistheaders
│ │ │ ├── AdapterWrapper.java
│ │ │ ├── CheckableWrapperView.java
│ │ │ ├── DistinctMultiHashMap.java
│ │ │ ├── DualHashMap.java
│ │ │ ├── ExpandableStickyListHeadersAdapter.java
│ │ │ ├── ExpandableStickyListHeadersListView.java
│ │ │ ├── SectionIndexerAdapterWrapper.java
│ │ │ ├── StickyListHeadersAdapter.java
│ │ │ ├── StickyListHeadersListView.java
│ │ │ ├── WrapperView.java
│ │ │ └── WrapperViewList.java
│ ├── jniLibs
│ │ └── armeabi
│ │ │ └── libmsc.so
│ └── res
│ │ ├── drawable
│ │ └── ptr_rotate_arrow.png
│ │ ├── layout
│ │ ├── activity_dialog_input_name.xml
│ │ ├── activity_face_detail.xml
│ │ ├── activity_login.xml
│ │ ├── activity_main.xml
│ │ ├── activity_manage.xml
│ │ ├── activity_sign_log.xml
│ │ ├── activity_video.xml
│ │ ├── activity_view_picture.xml
│ │ ├── cube_ptr_classic_default_header.xml
│ │ ├── cube_ptr_simple_loading.xml
│ │ ├── dialog_sign_in_success.xml
│ │ ├── header.xml
│ │ ├── list_footer.xml
│ │ ├── list_header.xml
│ │ ├── recyclerview_face_detail_item.xml
│ │ ├── recycleview_manage_item.xml
│ │ └── sticky_list_item_layout.xml
│ │ ├── menu
│ │ ├── base_toolbar_menu.xml
│ │ ├── face_detail_toobar_menu.xml
│ │ └── sign_log_toobar_menu.xml
│ │ ├── mipmap-hdpi
│ │ ├── button_login_press.png
│ │ ├── button_tijiao.png
│ │ ├── button_tijiao_press.png
│ │ ├── ic_launcher.png
│ │ └── login_icon.png
│ │ ├── mipmap-mdpi
│ │ ├── button_login.png
│ │ ├── button_login_press.png
│ │ ├── button_tijiao.png
│ │ ├── button_tijiao_press.png
│ │ ├── ic_launcher.png
│ │ └── login_icon.png
│ │ ├── mipmap-xhdpi
│ │ ├── add_face_picture.png
│ │ ├── app_icon.png
│ │ ├── bacground_2.png
│ │ ├── button_back.png
│ │ ├── button_login.png
│ │ ├── button_login_press.png
│ │ ├── button_tijiao.png
│ │ ├── button_tijiao_press.png
│ │ ├── delete_image.png
│ │ ├── delete_picture.png
│ │ ├── detail_picture.png
│ │ ├── edit_button.png
│ │ ├── ic_launcher.png
│ │ ├── loading.jpg
│ │ ├── login_icon.png
│ │ └── no_face.jpg
│ │ ├── mipmap-xxhdpi
│ │ ├── bacground_1.png
│ │ ├── button_login.png
│ │ ├── button_login_press.png
│ │ ├── button_tijiao.png
│ │ ├── button_tijiao_press.png
│ │ ├── ic_launcher.png
│ │ ├── sign_failed.png
│ │ ├── sign_log_title.png
│ │ └── sign_success.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── arrays.xml
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── cube_ptr_attrs.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── henu
│ └── swface
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the ART/Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 | out/
15 |
16 | # Gradle files
17 | .gradle/
18 | build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
29 | # Android Studio Navigation editor temp files
30 | .navigation/
31 |
32 | # Android Studio captures folder
33 | captures/
34 |
35 | # Intellij
36 | *.iml
37 | .idea/workspace.xml
38 |
39 | # Keystore files
40 | *.jks
41 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/libraries/BmobSDK_3_5_3_20161116.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/FaceppSDK.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/Msc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/android_android_24.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/animated_vector_drawable_24_2_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/appcompat_v7_24_2_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/constraint_layout_1_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/constraint_layout_solver_1_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/converter_gson_2_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/espresso_core_2_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/espresso_idling_resource_2_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/exposed_instrumentation_api_publish_0_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/eyekey_sdk_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/gson_2_7.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/hamcrest_core_1_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/hamcrest_integration_1_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/hamcrest_library_1_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/javawriter_2_1_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/javax_annotation_api_1_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/javax_inject_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/jsr305_2_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/junit_4_12.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/okhttp_3_4_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/okio_1_9_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/org_apache_http_legacy.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/org_apache_http_legacy_android_24.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/picasso_2_4_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/recyclerview_v7_24_2_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/libraries/retrofit_2_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/rules_0_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/.idea/libraries/runner_0_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/.idea/libraries/rxandroid_1_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/rxjava_1_1_6.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/libraries/support_annotations_24_2_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/support_compat_24_2_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/support_core_ui_24_2_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/support_core_utils_24_2_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/support_fragment_24_2_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/support_media_compat_24_2_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/support_v4_24_2_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/support_vector_drawable_24_2_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/misc.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 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Swface
2 | 人脸识别签到系统,基于科大讯飞人脸识别和Face++人脸识别api
3 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 24
5 | buildToolsVersion "25.0.0"
6 | useLibrary 'org.apache.http.legacy'
7 | defaultConfig {
8 | applicationId "com.henu.swface"
9 | minSdkVersion 15
10 | targetSdkVersion 22
11 | versionCode 1
12 | versionName "1.0"
13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
14 | }
15 | sourceSets {
16 | main.jniLibs.srcDirs = ['libs']
17 | }
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
22 | }
23 |
24 | // packagingOptions {
25 | // exclude 'META-INF/DEPENDENCIES'
26 | //// exclude 'META-INF/NOTICE'
27 | // exclude 'META-INF/LICENSE'
28 | //// exclude 'META-INF/LICENSE.txt'
29 | //// exclude 'META-INF/NOTICE.txt'
30 | //// exclude 'META-INF/ASL2.0'
31 | //// exclude 'META-INF/notice.txt'
32 | // }
33 | }
34 | }
35 |
36 | dependencies {
37 | compile fileTree(include: ['*.jar'], dir: 'libs')
38 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
39 | exclude group: 'com.android.support', module: 'support-annotations'
40 | })
41 | compile files('libs/converter-gson-2.1.0.jar')
42 | compile files('libs/eyekey-sdk_2.2.jar')
43 | compile files('libs/gson-2.7.jar')
44 | compile files('libs/okhttp-3.4.1.jar')
45 | compile files('libs/okio-1.9.0.jar')
46 | compile files('libs/retrofit-2.1.0.jar')
47 | compile files('libs/FaceppSDK.jar')
48 | compile files('libs/org.apache.http.legacy.jar')
49 | compile files('libs/BmobSDK_3.5.3_20161116.jar')
50 | compile files('libs/rxandroid-1.2.0.jar')
51 | compile files('libs/rxjava-1.1.6.jar')
52 | compile 'com.android.support:appcompat-v7:24.2.1'
53 | compile 'com.android.support:recyclerview-v7:24.2.1'
54 | compile 'com.android.support.constraint:constraint-layout:1.0.1'
55 | testCompile 'junit:junit:4.12'
56 | }
57 |
--------------------------------------------------------------------------------
/app/libs/BmobSDK_3.5.3_20161116.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/BmobSDK_3.5.3_20161116.jar
--------------------------------------------------------------------------------
/app/libs/FaceppSDK.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/FaceppSDK.jar
--------------------------------------------------------------------------------
/app/libs/Msc.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/Msc.jar
--------------------------------------------------------------------------------
/app/libs/arm64-v8a/libBmobStat.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/arm64-v8a/libBmobStat.so
--------------------------------------------------------------------------------
/app/libs/arm64-v8a/libbmob.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/arm64-v8a/libbmob.so
--------------------------------------------------------------------------------
/app/libs/arm64-v8a/libmsc.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/arm64-v8a/libmsc.so
--------------------------------------------------------------------------------
/app/libs/armeabi-v7a/libBmobStat.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/armeabi-v7a/libBmobStat.so
--------------------------------------------------------------------------------
/app/libs/armeabi-v7a/libbmob.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/armeabi-v7a/libbmob.so
--------------------------------------------------------------------------------
/app/libs/armeabi-v7a/libmsc.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/armeabi-v7a/libmsc.so
--------------------------------------------------------------------------------
/app/libs/armeabi/libBmobStat.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/armeabi/libBmobStat.so
--------------------------------------------------------------------------------
/app/libs/armeabi/libbmob.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/armeabi/libbmob.so
--------------------------------------------------------------------------------
/app/libs/armeabi/libmsc.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/armeabi/libmsc.so
--------------------------------------------------------------------------------
/app/libs/converter-gson-2.1.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/converter-gson-2.1.0.jar
--------------------------------------------------------------------------------
/app/libs/eyekey-sdk_2.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/eyekey-sdk_2.2.jar
--------------------------------------------------------------------------------
/app/libs/gson-2.7.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/gson-2.7.jar
--------------------------------------------------------------------------------
/app/libs/mips/libBmobStat.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/mips/libBmobStat.so
--------------------------------------------------------------------------------
/app/libs/mips/libbmob.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/mips/libbmob.so
--------------------------------------------------------------------------------
/app/libs/mips64/libBmobStat.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/mips64/libBmobStat.so
--------------------------------------------------------------------------------
/app/libs/mips64/libbmob.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/mips64/libbmob.so
--------------------------------------------------------------------------------
/app/libs/okhttp-3.4.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/okhttp-3.4.1.jar
--------------------------------------------------------------------------------
/app/libs/okio-1.9.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/okio-1.9.0.jar
--------------------------------------------------------------------------------
/app/libs/org.apache.http.legacy.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/org.apache.http.legacy.jar
--------------------------------------------------------------------------------
/app/libs/picasso-2.4.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/picasso-2.4.0.jar
--------------------------------------------------------------------------------
/app/libs/retrofit-2.1.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/retrofit-2.1.0.jar
--------------------------------------------------------------------------------
/app/libs/rxandroid-1.2.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/rxandroid-1.2.0.jar
--------------------------------------------------------------------------------
/app/libs/rxjava-1.1.6.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/rxjava-1.1.6.jar
--------------------------------------------------------------------------------
/app/libs/x86/libBmobStat.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/x86/libBmobStat.so
--------------------------------------------------------------------------------
/app/libs/x86/libbmob.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/x86/libbmob.so
--------------------------------------------------------------------------------
/app/libs/x86_64/libBmobStat.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/x86_64/libBmobStat.so
--------------------------------------------------------------------------------
/app/libs/x86_64/libbmob.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tony-Shx/Swface/9f1ca75a0fd88ddc1e7a2746adaea3dd7f1a1a28/app/libs/x86_64/libbmob.so
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Users\Administrator\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/henu/swface/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.henu.swface;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.henu.swface", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
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 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/java/com/henu/swface/Adapter/FaceDetailAdapter.java:
--------------------------------------------------------------------------------
1 | package com.henu.swface.Adapter;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.net.Uri;
6 | import android.os.Vibrator;
7 | import android.support.v7.widget.RecyclerView;
8 | import android.util.Log;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.widget.ImageView;
13 |
14 | import com.henu.swface.R;
15 | import com.henu.swface.VO.UserHasSigned;
16 | import com.henu.swface.activity.AddFaceActivity;
17 | import com.henu.swface.activity.RegisterFaceActivity;
18 | import com.squareup.picasso.Picasso;
19 |
20 | import java.util.List;
21 |
22 | /**
23 | * Created by 宋浩祥 on 2017/4/15.
24 | */
25 |
26 | public class FaceDetailAdapter extends RecyclerView.Adapter {
27 |
28 | private List imageList;
29 | private OnItemLongClickListener onItemLongClickListener;
30 | private static final String TAG = FaceDetailAdapter.class.getSimpleName();
31 | private OnDeleteClickListener onDeleteClickListener;
32 | private OnFaceClickListener onFaceClickListener;
33 | private int imageView_width = -1;
34 | private boolean onLongClick = false;
35 |
36 | public void setOnLongClick(boolean onLongClick) {
37 | this.onLongClick = onLongClick;
38 | }
39 |
40 | public FaceDetailAdapter(List imageList) {
41 | this.imageList = imageList;
42 | }
43 |
44 | @Override
45 | public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
46 | final Context context = parent.getContext();
47 | //获取屏幕宽度便于动态改变imageview长宽
48 | if (imageView_width < 0) {
49 | imageView_width = (parent.getWidth() - 30) / 3;
50 | }
51 | View view = LayoutInflater.from(context).inflate(R.layout.recyclerview_face_detail_item, parent, false);
52 | final ViewHolder viewHolder = new ViewHolder(view);
53 |
54 | if (onFaceClickListener != null) {
55 | viewHolder.imageView_face_detail.setOnClickListener(new View.OnClickListener() {
56 | @Override
57 | public void onClick(View view) {
58 | int position = viewHolder.getAdapterPosition();
59 | onFaceClickListener.onFaceClick(view,position);
60 | }
61 | });
62 | }
63 | if (onItemLongClickListener != null) {
64 | viewHolder.imageView_face_detail.setOnLongClickListener(new View.OnLongClickListener() {
65 | @Override
66 | public boolean onLongClick(View view) {
67 | int position = viewHolder.getAdapterPosition();
68 | Log.i(TAG, "onLongClick: " + position);
69 | if (position < imageList.size()) {
70 | onLongClick = true;
71 | onItemLongClickListener.onItemLongClick(view);
72 | }
73 | return false;
74 | }
75 | });
76 | }
77 |
78 | if (onDeleteClickListener != null) {
79 | viewHolder.imageView_delete_face_detail.setOnClickListener(new View.OnClickListener() {
80 | @Override
81 | public void onClick(View view) {
82 | if (onLongClick) {
83 | int position = viewHolder.getAdapterPosition();
84 | onDeleteClickListener.onDeleteClick(view, position);
85 | }
86 | }
87 | });
88 | }
89 | return viewHolder;
90 | }
91 |
92 |
93 | @Override
94 | public void onBindViewHolder(ViewHolder holder, int position) {
95 | Context context = holder.itemView.getContext();
96 | if (position < imageList.size()) {
97 | if (onLongClick) {
98 | holder.imageView_delete_face_detail.setVisibility(View.VISIBLE);
99 | } else {
100 | holder.imageView_delete_face_detail.setVisibility(View.GONE);
101 | }
102 | Uri imagePath = imageList.get(position);
103 | Picasso.with(context).load(imagePath).placeholder(R.mipmap.loading).into(holder.imageView_face_detail);
104 | } else {
105 | Picasso.with(context).load(R.mipmap.add_face_picture).placeholder(R.mipmap.loading).into(holder.imageView_face_detail);
106 | }
107 | if (imageView_width > 0) {
108 | //动态改变imageview长宽使其保持正方形
109 | ViewGroup.LayoutParams ps = holder.imageView_face_detail.getLayoutParams();
110 | ps.height = imageView_width;
111 | holder.imageView_face_detail.setLayoutParams(ps);
112 | }
113 | }
114 |
115 | @Override
116 | public int getItemCount() {
117 | if (imageList.size() < 5) {
118 | return imageList.size() + 1;
119 | } else {
120 | return imageList.size();
121 | }
122 | }
123 |
124 | static class ViewHolder extends RecyclerView.ViewHolder {
125 | ImageView imageView_face_detail;
126 | ImageView imageView_delete_face_detail;
127 |
128 | public ViewHolder(View itemView) {
129 | super(itemView);
130 | imageView_face_detail = (ImageView) itemView.findViewById(R.id.imageView_face_detail);
131 | imageView_delete_face_detail = (ImageView) itemView.findViewById(R.id.imageView_delete_face_detail);
132 |
133 | }
134 | }
135 |
136 | public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) {
137 | this.onItemLongClickListener = onItemLongClickListener;
138 | }
139 |
140 | public void setOnDeleteClickListener(OnDeleteClickListener onDeleteClickListener) {
141 | this.onDeleteClickListener = onDeleteClickListener;
142 | }
143 |
144 | public void setOnFaceClickListener(OnFaceClickListener onFaceClickListener) {
145 | this.onFaceClickListener = onFaceClickListener;
146 | }
147 |
148 |
149 | public interface OnItemLongClickListener {
150 | void onItemLongClick(View view);
151 | }
152 |
153 | public interface OnDeleteClickListener {
154 | void onDeleteClick(View view, int index);
155 | }
156 |
157 | public interface OnFaceClickListener {
158 | void onFaceClick(View view,int position);
159 | }
160 |
161 | }
162 |
--------------------------------------------------------------------------------
/app/src/main/java/com/henu/swface/Database/DatabaseHelper.java:
--------------------------------------------------------------------------------
1 | package com.henu.swface.Database;
2 |
3 | import android.content.Context;
4 | import android.database.sqlite.SQLiteDatabase;
5 | import android.database.sqlite.SQLiteOpenHelper;
6 |
7 | /**
8 | * Created by 宋浩祥 on 2017/3/7.
9 | */
10 |
11 | public class DatabaseHelper extends SQLiteOpenHelper {
12 |
13 | private static final String DB_NAME = "Swface.db";
14 | private static final int version = 1;
15 | private static final String CREATE_TABLE_FACES = "CREATE TABLE IF NOT EXISTS Faces(id INTEGER PRIMARY KEY AUTOINCREMENT," +
16 | "request_id TEXT,gender TEXT,glass TEXT,ethnicity TEXT," +
17 | "time_used INTEGER,age INTEGER,face_rectangle_width INTEGER,face_rectangle_top INTEGER," +
18 | "face_rectangle_left INTEGER,face_rectangle_height INTEGER," +
19 | "left_normal_glass_eye_open REAL,left_no_glass_eye_close REAL,left_occlusion REAL," +
20 | "left_no_glass_eye_open REAL,left_normal_glass_eye_close REAL,left_dark_glasses REAL," +
21 | "right_normal_glass_eye_open REAL,right_no_glass_eye_close REAL,right_occlusion REAL," +
22 | "right_no_glass_eye_open REAL,right_normal_glass_eye_close REAL,right_dark_glasses REAL," +
23 | "headpose_yaw_angle REAL,headpose_pitch_angle REAL,headpose_roll_angle REAL,blurness REAL," +
24 | "smile REAL,facequality REAL,face_token TEXT,image_path TEXT)";
25 | private static final String DROP_TABLE_FACES = "DROP TABLE IF EXISTS Faces";
26 | private static final String CREATE_TABLE_USER = "CREATE TABLE IF NOT EXISTS UserHasSigned(object_id TEXT PRIMARY KEY," +
27 | "user_name TEXT,face_token1 TEXT,face_token2 TEXT,face_token3 TEXT,face_token4 TEXT,face_token5 TEXT,face_url1 TEXT," +
28 | "face_url2 TEXT,face_url3 TEXT,face_url4 TEXT,face_url5 TEXT,created_at TEXT,updated_at TEXT)";
29 | private static final String DROP_TABLE_USER = "DROP TABLE IF EXISTS UserHasSigned";
30 | private static final String CREATE_TABLE_SIGNLOG = "CREATE TABLE IF NOT EXISTS SignLog(id INTEGER PRIMARY KEY AUTOINCREMENT," +
31 | "object_id TEXT,user_name TEXT,confidence REAL,time NUMERIC)";
32 | private static final String DROP_TABLE_SIGNLOG = "DROP TABLE IF EXISTS SignLog";
33 |
34 | public DatabaseHelper(Context context) {
35 | super(context, DB_NAME, null, version);
36 | }
37 |
38 | @Override
39 | public void onCreate(SQLiteDatabase db) {
40 | db.execSQL(CREATE_TABLE_FACES);
41 | db.execSQL(CREATE_TABLE_USER);
42 | db.execSQL(CREATE_TABLE_SIGNLOG);
43 | }
44 |
45 | @Override
46 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
47 | db.execSQL(DROP_TABLE_FACES);
48 | db.execSQL(DROP_TABLE_USER);
49 | db.execSQL(DROP_TABLE_SIGNLOG);
50 | db.execSQL(CREATE_TABLE_FACES);
51 | db.execSQL(CREATE_TABLE_USER);
52 | db.execSQL(CREATE_TABLE_SIGNLOG);
53 |
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/com/henu/swface/Database/FaceMetaData.java:
--------------------------------------------------------------------------------
1 | package com.henu.swface.Database;
2 |
3 | import android.provider.BaseColumns;
4 |
5 | /**
6 | * Created by 宋浩祥 on 2017/3/7.
7 | */
8 |
9 | public final class FaceMetaData {
10 | private FaceMetaData() {
11 | }
12 |
13 |
14 |
15 |
16 | public static abstract class FaceTable implements BaseColumns{
17 | public static final String TABLE_NAME = "Faces";
18 | public static final String REQUEST_ID = "request_id";
19 | public static final String GENDER = "gender";
20 | public static final String GLASS = "glass";
21 | public static final String ETHNICITY = "ethnicity";
22 | public static final String TIME_USED = "time_used";
23 | public static final String AGE = "age";
24 | public static final String FACE_RECTANGLE_WIDTH = "face_rectangle_width";
25 | public static final String FACE_RECTANGLE_TOP = "face_rectangle_top";
26 | public static final String FACE_RECTANGLE_LEFT = "face_rectangle_left";
27 | public static final String FACE_RECTANGLE_HEIGHT = "face_rectangle_height";
28 | public static final String LEFT_NORMAL_GLASS_EYE_OPEN = "left_normal_glass_eye_open";
29 | public static final String LEFT_NO_GLASS_EYE_CLOSE = "left_no_glass_eye_close";
30 | public static final String LEFT_OCCLUSION = "left_occlusion";
31 | public static final String LEFT_NO_GLASS_EYE_OPEN = "left_no_glass_eye_open";
32 | public static final String LEFT_NORMAL_GLASS_EYE_CLOSE ="left_normal_glass_eye_close";
33 | public static final String LEFT_DARK_GLASSES = "left_dark_glasses";
34 | public static final String RIGHT_NORMAL_GLASS_EYE_OPEN = "right_normal_glass_eye_open";
35 | public static final String RIGHT_NO_GLASS_EYE_CLOSE = "right_no_glass_eye_close";
36 | public static final String RIGHT_OCCLUSION = "right_occlusion";
37 | public static final String RIGHT_NO_GLASS_EYE_OPEN = "right_no_glass_eye_open";
38 | public static final String RIGHT_NORMAL_GLASS_EYE_CLOSE = "right_normal_glass_eye_close";
39 | public static final String RIGHT_DARK_GLASSES = "right_dark_glasses";
40 | public static final String HEADPOSE_YAW_ANGLE = "headpose_yaw_angle";
41 | public static final String HEADPOSE_PITCH_ANGLE = "headpose_pitch_angle";
42 | public static final String HEADPOSE_ROLL_ANGLE = "headpose_roll_angle";
43 | public static final String BLURNESS = "blurness";
44 | public static final String SMILE = "smile";
45 | public static final String FACEQUALITY = "facequality";
46 | public static final String FACE_TOKEN = "face_token";
47 | public static final String IMAGE_PATH = "image_path";
48 |
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/henu/swface/Database/SignLogData.java:
--------------------------------------------------------------------------------
1 | package com.henu.swface.Database;
2 |
3 | import android.provider.BaseColumns;
4 |
5 | /**
6 | * Created by 宋浩祥 on 2017/4/4.
7 | */
8 |
9 | public final class SignLogData{
10 | public SignLogData() {
11 | }
12 |
13 | public static abstract class SignLogTable implements BaseColumns{
14 | public static final String TABLE_NAME = "SignLog";
15 | public static final String OBJECT_ID = "object_id";
16 | public static final String USER_NAME = "user_name";
17 | public static final String CONFIDENCE = "confidence";
18 | public static final String TIME = "time";
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/henu/swface/Database/UserMetaData.java:
--------------------------------------------------------------------------------
1 | package com.henu.swface.Database;
2 |
3 | import android.provider.BaseColumns;
4 |
5 | /**
6 | * Created by Administrator on 2017/3/29.
7 | */
8 |
9 | public final class UserMetaData {
10 | public UserMetaData() {
11 | }
12 | public static abstract class UserTable implements BaseColumns{
13 | public static final String TABLE_NAME = "UserHasSigned";
14 | public static final String OBJECT_ID = "object_id";
15 | public static final String USER_NAME = "user_name";
16 | public static final String FACE_TOKEN1 = "face_token1";
17 | public static final String FACE_TOKEN2 = "face_token2";
18 | public static final String FACE_TOKEN3 = "face_token3";
19 | public static final String FACE_TOKEN4 = "face_token4";
20 | public static final String FACE_TOKEN5 = "face_token5";
21 | public static final String FACE_URL1 = "face_url1";
22 | public static final String FACE_URL2 = "face_url2";
23 | public static final String FACE_URL3 = "face_url3";
24 | public static final String FACE_URL4 = "face_url4";
25 | public static final String FACE_URL5 = "face_url5";
26 | public static final String CREATED_AT = "created_at";
27 | public static final String UPDATED_AT = "updated_at";
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/henu/swface/MyApplication.java:
--------------------------------------------------------------------------------
1 | package com.henu.swface;
2 |
3 | import android.app.Application;
4 | import android.util.Log;
5 |
6 | import cn.bmob.v3.Bmob;
7 |
8 | /**
9 | * Created by Administrator on 2017/4/20.
10 | */
11 |
12 | public class MyApplication extends Application {
13 |
14 | @Override
15 | public void onCreate() {
16 | super.onCreate();
17 | //第一:默认初始化
18 | Bmob.initialize(this, "6e64317b6509bb503f7d9ab8404bf54c");
19 | Log.i("onCreate: ","bmob!!!!");
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/henu/swface/Utils/DateUtil.java:
--------------------------------------------------------------------------------
1 | package com.henu.swface.Utils;
2 |
3 | import android.provider.ContactsContract;
4 |
5 | import java.util.Calendar;
6 | import java.util.Date;
7 |
8 | /**
9 | * Created by Administrator on 2017/5/30.
10 | */
11 |
12 | public class DateUtil {
13 |
14 | public static Date getDateFromLong(long time){
15 | Calendar calendar = Calendar.getInstance();
16 | calendar.setTimeInMillis(time);
17 | return calendar.getTime();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/henu/swface/Utils/FaceRect.java:
--------------------------------------------------------------------------------
1 | package com.henu.swface.Utils;
2 |
3 | import android.graphics.Point;
4 | import android.graphics.Rect;
5 |
6 | /**
7 | * @author 宋浩祥
8 | * FaceRect是用于表示人脸检测的结果,其中包括了 人脸的角度、得分、检测框位置、关键点
9 | */
10 | public class FaceRect {
11 | public float score;
12 |
13 | public Rect bound = new Rect();
14 | public Point point[];
15 |
16 | public Rect raw_bound = new Rect();
17 | public Point raw_point[];
18 |
19 | @Override
20 | public String toString() {
21 | return bound.toString();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/henu/swface/Utils/FaceSetUtil.java:
--------------------------------------------------------------------------------
1 | package com.henu.swface.Utils;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 |
6 | import java.io.File;
7 | import java.io.IOException;
8 |
9 | import okhttp3.MediaType;
10 | import okhttp3.MultipartBody;
11 | import okhttp3.OkHttpClient;
12 | import okhttp3.Request;
13 | import okhttp3.RequestBody;
14 | import okhttp3.Response;
15 |
16 | /**
17 | * Created by Administrator on 2017/4/22.
18 | */
19 |
20 | public class FaceSetUtil {
21 | public static Response searchFaceset(Context context, String API_KEY, String API_Secret, File imageFile) {
22 | OkHttpClient client = new OkHttpClient();
23 | RequestBody requestBody = postBodySearchFaceSet(context, API_KEY, API_Secret, imageFile);
24 | Request request = new Request.Builder().url("https://api-cn.faceplusplus.com/facepp/v3/search")
25 | .post(requestBody).build();
26 | Response response = null;
27 | try {
28 | int attemp = 0;
29 | do {
30 | try {
31 | Thread.sleep(50);
32 | } catch (InterruptedException e) {
33 | e.printStackTrace();
34 | }
35 | response = client.newCall(request).execute();
36 | attemp++;
37 | } while (response.code() != 200 && attemp < 10);
38 | } catch (IOException e) {
39 | e.printStackTrace();
40 | }
41 | return response;
42 | }
43 |
44 | protected static RequestBody postBodySearchFaceSet(Context context, String API_KEY, String API_Secret, File file) {
45 | // 设置请求体
46 | MediaType MEDIA_TYPE_JPG = MediaType.parse("image/jpg");
47 | RequestBody body = MultipartBody.create(MEDIA_TYPE_JPG, file);
48 | MultipartBody.Builder builder = new MultipartBody.Builder();
49 | builder.setType(MultipartBody.FORM);
50 | //这里是 封装上传图片参数
51 | builder.addFormDataPart("api_key", API_KEY);
52 | builder.addFormDataPart("api_secret", API_Secret);
53 | builder.addFormDataPart("image_file", file.getName(), body);
54 | SharedPreferences sp = context.getSharedPreferences("login", Context.MODE_PRIVATE);
55 | String outerId = sp.getString("username", "default");
56 | builder.addFormDataPart("outer_id", outerId);
57 | return builder.build();
58 | }
59 |
60 | public static Response createFaceSet(String API_KEY, String API_Secret, String display_name, String outer_id, String face_token) {
61 | OkHttpClient client = new OkHttpClient();
62 | //封装请求体
63 | RequestBody requestBody = postBodyCreateFaceSet(API_KEY, API_Secret, display_name, outer_id, face_token);
64 | Request request = new Request.Builder().url("https://api-cn.faceplusplus.com/facepp/v3/faceset/create")
65 | .post(requestBody).build();
66 | Response response = null;
67 | try {
68 | response = client.newCall(request).execute();
69 | } catch (IOException e) {
70 | e.printStackTrace();
71 | }
72 | return response;
73 | }
74 |
75 | private static RequestBody postBodyCreateFaceSet(String API_KEY, String API_Secret, String display_name, String outer_id, String face_token) {
76 | // 设置请求体
77 | MultipartBody.Builder builder = new MultipartBody.Builder();
78 | builder.setType(MultipartBody.FORM);
79 | builder.addFormDataPart("api_key", API_KEY);
80 | builder.addFormDataPart("api_secret", API_Secret);
81 | builder.addFormDataPart("display_name", display_name);
82 | builder.addFormDataPart("outer_id", outer_id);
83 | builder.addFormDataPart("face_tokens", face_token);
84 | builder.addFormDataPart("force_merge", "1");
85 | return builder.build();
86 | }
87 |
88 | public static Response removeFaceFormFaceSet(String API_KEY, String API_Secret, String outer_id, String face_token){
89 | OkHttpClient client = new OkHttpClient();
90 | RequestBody requestBody = postBodyRemoveFaceFormFaceSet(API_KEY, API_Secret, outer_id,face_token);
91 | Request request = new Request.Builder().url("https://api-cn.faceplusplus.com/facepp/v3/faceset/removeface")
92 | .post(requestBody).build();
93 | Response response = null;
94 | try {
95 | int attemp = 0;
96 | do {
97 | try {
98 | Thread.sleep(50);
99 | } catch (InterruptedException e) {
100 | e.printStackTrace();
101 | }
102 | response = client.newCall(request).execute();
103 | attemp++;
104 | } while (response.code() != 200 && attemp < 10);
105 | } catch (IOException e) {
106 | e.printStackTrace();
107 | }
108 | return response;
109 | }
110 |
111 | private static RequestBody postBodyRemoveFaceFormFaceSet(String API_KEY, String API_Secret, String outer_id, String face_token){
112 | // 设置请求体
113 | MultipartBody.Builder builder = new MultipartBody.Builder();
114 | builder.setType(MultipartBody.FORM);
115 | builder.addFormDataPart("api_key", API_KEY);
116 | builder.addFormDataPart("api_secret", API_Secret);
117 | builder.addFormDataPart("outer_id", outer_id);
118 | builder.addFormDataPart("face_tokens", face_token);
119 | return builder.build();
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/app/src/main/java/com/henu/swface/Utils/FaceUtil.java:
--------------------------------------------------------------------------------
1 | package com.henu.swface.Utils;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.content.SharedPreferences;
7 | import android.graphics.Bitmap;
8 | import android.graphics.BitmapFactory;
9 | import android.graphics.Canvas;
10 | import android.graphics.Color;
11 | import android.graphics.Matrix;
12 | import android.graphics.Paint;
13 | import android.graphics.Paint.Style;
14 | import android.graphics.Point;
15 | import android.graphics.Rect;
16 | import android.media.ExifInterface;
17 | import android.net.Uri;
18 | import android.os.Environment;
19 | import android.provider.MediaStore;
20 |
21 | import java.io.BufferedOutputStream;
22 | import java.io.File;
23 | import java.io.FileFilter;
24 | import java.io.FileNotFoundException;
25 | import java.io.FileOutputStream;
26 | import java.io.IOException;
27 | import java.util.regex.Pattern;
28 |
29 | import okhttp3.MediaType;
30 | import okhttp3.MultipartBody;
31 | import okhttp3.OkHttpClient;
32 | import okhttp3.Request;
33 | import okhttp3.RequestBody;
34 | import okhttp3.Response;
35 |
36 | public class FaceUtil {
37 |
38 |
39 | public static Response detectFace(String faceToken, String API_KEY, String API_Secret) {
40 | OkHttpClient client = new OkHttpClient();
41 | //封装请求体
42 | RequestBody requestBody = postBodyDetectFace(faceToken, API_KEY, API_Secret);
43 | Request request = new Request.Builder().url("https://api-cn.faceplusplus.com/facepp/v3/face/analyze")
44 | .post(requestBody).build();
45 | Response response = null;
46 | try {
47 | response = client.newCall(request).execute();
48 | int attemp = 0;
49 | while (response.code() != 200 && attemp < 10){
50 | try {
51 | Thread.sleep(50);
52 | } catch (InterruptedException e) {
53 | e.printStackTrace();
54 | }
55 | response = client.newCall(request).execute();
56 | attemp++;
57 | }
58 | } catch (IOException e) {
59 | e.printStackTrace();
60 | }
61 | return response;
62 | }
63 | public static Response detectFace(File imageFile, String API_KEY, String API_Secret) {
64 | OkHttpClient client = new OkHttpClient();
65 | //封装请求体
66 | RequestBody requestBody = postBodyDetectFace(imageFile, API_KEY, API_Secret);
67 | Request request = new Request.Builder().url("https://api-cn.faceplusplus.com/facepp/v3/detect")
68 | .post(requestBody).build();
69 | Response response = null;
70 | try {
71 | response = client.newCall(request).execute();
72 | } catch (IOException e) {
73 | e.printStackTrace();
74 | }
75 | return response;
76 | }
77 | private static RequestBody postBodyDetectFace(String faceToken, String API_KEY, String API_Secret) {
78 |
79 | MultipartBody.Builder builder = new MultipartBody.Builder();
80 | builder.setType(MultipartBody.FORM);
81 | builder.addFormDataPart("api_key", API_KEY);
82 | builder.addFormDataPart("api_secret", API_Secret);
83 | builder.addFormDataPart("face_tokens", faceToken);
84 | //builder.addFormDataPart("return_landmark", "1");
85 | builder.addFormDataPart("return_attributes", "gender,age,smiling,headpose,facequality,blur,eyestatus,ethnicity");
86 | return builder.build();
87 | }
88 |
89 |
90 |
91 |
92 | private static RequestBody postBodyDetectFace(File file, String API_KEY, String API_Secret) {
93 | // 设置请求体
94 | MediaType MEDIA_TYPE_JPG = MediaType.parse("image/jpg");
95 | RequestBody body = MultipartBody.create(MEDIA_TYPE_JPG, file);
96 | MultipartBody.Builder builder = new MultipartBody.Builder();
97 | builder.setType(MultipartBody.FORM);
98 | builder.addFormDataPart("api_key", API_KEY);
99 | builder.addFormDataPart("api_secret", API_Secret);
100 | builder.addFormDataPart("image_file", file.getName(), body);
101 | //builder.addFormDataPart("return_landmark", "1");
102 | builder.addFormDataPart("return_attributes", "gender,age,smiling,headpose,facequality,blur,eyestatus,ethnicity");
103 | return builder.build();
104 | }
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/app/src/main/java/com/henu/swface/Utils/FinalUtil.java:
--------------------------------------------------------------------------------
1 | package com.henu.swface.Utils;
2 |
3 | /**
4 | * Created by Administrator on 2017/4/16.
5 | */
6 |
7 | public final class FinalUtil {
8 | //face++的api_key
9 | public final static String API_KEY = "lJsij4n8pYEj3bW-tSJqEhRgkdfHobC8";
10 | public final static String API_Secret = "i1H3kRBBzJ2Wo_1T-6RsbRmWgcHAREww";
11 |
12 | public final static int DETECT_SUCCESS = 0X100;
13 | public final static int DETECT_FAILED_IO_EXCEPTION = 0X101;
14 | public final static int DETECT_FAILED_NO_FACE = 0X102;
15 | public final static int DETECT_FAILED_LIMIT_EXCEEDED = 0X103;
16 |
17 | public final static int UPDATE_PICTURE_SUCCESS = 0X120;
18 | public final static int UPDATE_PICTURE_EXCEPTION = 0X121;
19 |
20 | public static final int SIGN_IN_SUCCESS = 0x200;
21 | public final static int SIGN_IN_FAILED_IOEXCEPTION = 0x201;
22 | public final static int SIGN_IN_FAILED_FILENOTFIND = 0x202;
23 | public final static int SIGN_IN_FAILED_NOUSER = 0x203;
24 | public final static int ADDUSERSUCCESS = 0x210;
25 |
26 | public final static int UPDATE_DETAIL_SUCCESS = 0X300;
27 | public final static int UPDATE_DETAIL_IO_EXCEPTION = 0X301;
28 |
29 | public final static int ADD_FACE_SUCCESS = 0X400;
30 | public final static int ADD_FACE_IO_EXCEPTION = 0X401;
31 | public final static int ADD_FACE_TO_FACESET_SUCCESS = 0X410;
32 | public final static int ADD_FACE_TO_FACESET_EXCEPTION = 0X411;
33 |
34 | public final static int SYN_DATA_SUCCESS = 0x500;
35 | public final static int SYN_DATA_FAILED = 0x501;
36 |
37 | public final static int REMOVE_FACE_SUCCESS = 0X600;
38 | public final static int REMOVE_FACE_IO_EXCEPTION = 0X601;
39 | public final static int REMOVE_FACE_BMOB_EXCEPTION = 0X602;
40 |
41 | public final static int REMOVE_USER_SUCCESS = 0X700;
42 | public final static int REMOVE_USER_IO_EXCEPTION = 0X701;
43 | public final static int REMOVE_USER_BMOB_EXCEPTION = 0X702;
44 |
45 | public final static int LOAD_SIGN_LOG_SUCCESS = 0X800;
46 | public final static int LOAD_SIGN_LOG_IO_EXCEPTION = 0X801;
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/henu/swface/Utils/JSONUtil.java:
--------------------------------------------------------------------------------
1 | package com.henu.swface.Utils;
2 |
3 | import android.util.Log;
4 |
5 | import com.henu.swface.VO.Face;
6 | import com.henu.swface.VO.FaceSignIn;
7 |
8 | import org.json.JSONArray;
9 | import org.json.JSONException;
10 | import org.json.JSONObject;
11 |
12 | /**
13 | * Created by Administrator on 2017/3/24.
14 | */
15 |
16 | public class JSONUtil {
17 | private static final String TAG = "JSONUtil";
18 |
19 | public JSONUtil() {
20 | }
21 |
22 | public Face parseDetectFaceJSON(String JSON){
23 | System.out.println("!!!!!!!!!"+JSON);
24 | Face face = new Face();
25 | try {
26 | JSONObject jsonObject = new JSONObject(JSON);
27 | face.setRequest_id(jsonObject.get("request_id").toString());
28 | face.setTime_used(jsonObject.getInt("time_used"));
29 | JSONArray faceArray = jsonObject.getJSONArray("faces");
30 | if(faceArray==null){
31 | return null;
32 | }
33 | JSONObject faceObject = faceArray.getJSONObject(0);
34 | face.setFace_rectangle_width(faceObject.getJSONObject("face_rectangle").getInt("width"));
35 | face.setFace_rectangle_top(faceObject.getJSONObject("face_rectangle").getInt("top"));
36 | face.setFace_rectangle_left(faceObject.getJSONObject("face_rectangle").getInt("left"));
37 | face.setFace_rectangle_high(faceObject.getJSONObject("face_rectangle").getInt("height"));
38 | JSONObject attributesObject = faceObject.getJSONObject("attributes");
39 | face.setGender(attributesObject.getJSONObject("gender").get("value").toString());
40 | face.setAge(attributesObject.getJSONObject("age").getInt("value"));
41 | face.setGlass(attributesObject.getJSONObject("glass").get("value").toString());
42 | face.setHeadpose_yaw_angle(attributesObject.getJSONObject("headpose").getDouble("yaw_angle"));
43 | face.setHeadpose_pitch_angle(attributesObject.getJSONObject("headpose").getDouble("pitch_angle"));
44 | face.setHeadpose_roll_angle(attributesObject.getJSONObject("headpose").getDouble("roll_angle"));
45 | face.setSmile(attributesObject.getJSONObject("smile").getDouble("value"));
46 | face.setFacequality(attributesObject.getJSONObject("facequality").getDouble("value"));
47 | face.setEthnicity(attributesObject.getJSONObject("ethnicity").get("value").toString());
48 | face.setFace_token(faceObject.get("face_token").toString());
49 | JSONObject eyestatusObject = attributesObject.getJSONObject("eyestatus");
50 | face.setlNormalGlassEyeOpen(eyestatusObject.getJSONObject("left_eye_status").getDouble("normal_glass_eye_open"));
51 | face.setlNoGlassEyeClose(eyestatusObject.getJSONObject("left_eye_status").getDouble("no_glass_eye_close"));
52 | face.setLeft_occlusion(eyestatusObject.getJSONObject("left_eye_status").getDouble("occlusion"));
53 | face.setLeftNoGlassEyeOpen(eyestatusObject.getJSONObject("left_eye_status").getDouble("no_glass_eye_open"));
54 | face.setlNormalGlassEyeClose(eyestatusObject.getJSONObject("left_eye_status").getDouble("normal_glass_eye_close"));
55 | face.setLeft_dark_glasses(eyestatusObject.getJSONObject("left_eye_status").getDouble("dark_glasses"));
56 | face.setrNormalGlassEyeOpen(eyestatusObject.getJSONObject("right_eye_status").getDouble("normal_glass_eye_open"));
57 | face.setrNoGlassEyeClose(eyestatusObject.getJSONObject("right_eye_status").getDouble("no_glass_eye_close"));
58 | face.setRight_occlusion(eyestatusObject.getJSONObject("right_eye_status").getDouble("occlusion"));
59 | face.setrNoGlassEyeOpen(eyestatusObject.getJSONObject("right_eye_status").getDouble("no_glass_eye_open"));
60 | face.setrNormalGlassEyeClose(eyestatusObject.getJSONObject("right_eye_status").getDouble("normal_glass_eye_close"));
61 | face.setRight_dark_glasses(eyestatusObject.getJSONObject("right_eye_status").getDouble("dark_glasses"));
62 | face.setBlurness(attributesObject.getJSONObject("blur").getJSONObject("blurness").getDouble("value"));
63 | } catch (JSONException e) {
64 | e.printStackTrace();
65 | return null;
66 | }
67 | return face;
68 | }
69 |
70 | public FaceSignIn parseSearchFaceJSON(String JSON){
71 | Log.i(TAG, "parseSearchFaceJSON: " + JSON);
72 | FaceSignIn faceSignIn = new FaceSignIn();
73 | try {
74 | JSONObject jsonObject = new JSONObject(JSON);
75 | faceSignIn.setTime_used(jsonObject.getInt("time_used"));
76 | JSONObject thresholds = jsonObject.getJSONObject("thresholds");
77 | faceSignIn.setThresholds3(thresholds.getDouble("1e-3"));
78 | faceSignIn.setThresholds4(thresholds.getDouble("1e-4"));
79 | faceSignIn.setThresholds5(thresholds.getDouble("1e-5"));
80 | JSONArray results = jsonObject.getJSONArray("results");
81 | faceSignIn.setConfidence(results.getJSONObject(0).getDouble("confidence"));
82 | faceSignIn.setFace_token(results.getJSONObject(0).getString("face_token"));
83 | } catch (JSONException e) {
84 | e.printStackTrace();
85 | }
86 | Log.i(TAG, "parseSearchFaceJSON_faceSignIn: "+faceSignIn.toString());
87 | return faceSignIn;
88 |
89 | }
90 |
91 |
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/app/src/main/java/com/henu/swface/Utils/ParseResult.java:
--------------------------------------------------------------------------------
1 | package com.henu.swface.Utils;
2 |
3 | import android.graphics.Point;
4 | import android.text.TextUtils;
5 |
6 | import org.json.JSONArray;
7 | import org.json.JSONException;
8 | import org.json.JSONObject;
9 | import org.json.JSONTokener;
10 |
11 | import java.util.Iterator;
12 |
13 | public class ParseResult {
14 | /**
15 | * 离线人脸框结果解析方法
16 | * @param json
17 | * @return
18 | */
19 | static public FaceRect[] parseResult(String json){
20 | FaceRect[] rect = null;
21 | if(TextUtils.isEmpty(json)) {
22 | return null;
23 | }
24 | try {
25 | JSONTokener tokener = new JSONTokener(json);
26 | JSONObject joResult = new JSONObject(tokener);
27 | int ret = joResult.optInt("ret");
28 | if(ret != 0) {
29 | return null;
30 | }
31 | // 获取每个人脸的结果
32 | JSONArray items = joResult.getJSONArray("face");
33 | // 获取人脸数目
34 | rect = new FaceRect[items.length()];
35 | for(int i=0; i 0
13 | && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
14 | .getTop() < absListView.getPaddingTop());
15 | } else {
16 | return view.getScrollY() > 0;
17 | }
18 | } else {
19 | return view.canScrollVertically(-1);
20 | }
21 | }
22 |
23 | /**
24 | * Default implement for check can perform pull to refresh
25 | *
26 | * @param frame
27 | * @param content
28 | * @param header
29 | * @return
30 | */
31 | public static boolean checkContentCanBePulledDown(PtrFrameLayout frame, View content, View header) {
32 | return !canChildScrollUp(content);
33 | }
34 |
35 | @Override
36 | public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
37 | return checkContentCanBePulledDown(frame, content, header);
38 | }
39 | }
--------------------------------------------------------------------------------
/app/src/main/java/in/srain/cube/views/ptr/PtrHandler.java:
--------------------------------------------------------------------------------
1 | package in.srain.cube.views.ptr;
2 |
3 | import android.view.View;
4 |
5 | public interface PtrHandler {
6 |
7 | /**
8 | * Check can do refresh or not. For example the content is empty or the first child is in view.
9 | *
10 | * {@link in.srain.cube.views.ptr.PtrDefaultHandler#checkContentCanBePulledDown}
11 | */
12 | public boolean checkCanDoRefresh(final PtrFrameLayout frame, final View content, final View header);
13 |
14 | /**
15 | * When refresh begin
16 | *
17 | * @param frame
18 | */
19 | public void onRefreshBegin(final PtrFrameLayout frame);
20 | }
--------------------------------------------------------------------------------
/app/src/main/java/in/srain/cube/views/ptr/PtrUIHandler.java:
--------------------------------------------------------------------------------
1 | package in.srain.cube.views.ptr;
2 |
3 | import in.srain.cube.views.ptr.indicator.PtrIndicator;
4 |
5 | /**
6 | *
7 | */
8 | public interface PtrUIHandler {
9 |
10 | /**
11 | * When the content view has reached top and refresh has been completed, view will be reset.
12 | *
13 | * @param frame
14 | */
15 | public void onUIReset(PtrFrameLayout frame);
16 |
17 | /**
18 | * prepare for loading
19 | *
20 | * @param frame
21 | */
22 | public void onUIRefreshPrepare(PtrFrameLayout frame);
23 |
24 | /**
25 | * perform refreshing UI
26 | */
27 | public void onUIRefreshBegin(PtrFrameLayout frame);
28 |
29 | /**
30 | * perform UI after refresh
31 | */
32 | public void onUIRefreshComplete(PtrFrameLayout frame);
33 |
34 | public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator);
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/in/srain/cube/views/ptr/PtrUIHandlerHolder.java:
--------------------------------------------------------------------------------
1 | package in.srain.cube.views.ptr;
2 |
3 | import in.srain.cube.views.ptr.indicator.PtrIndicator;
4 |
5 | /**
6 | * A single linked list to wrap PtrUIHandler
7 | */
8 | class PtrUIHandlerHolder implements PtrUIHandler {
9 |
10 | private PtrUIHandler mHandler;
11 | private PtrUIHandlerHolder mNext;
12 |
13 | private boolean contains(PtrUIHandler handler) {
14 | return mHandler != null && mHandler == handler;
15 | }
16 |
17 | private PtrUIHandlerHolder() {
18 |
19 | }
20 |
21 | public boolean hasHandler() {
22 | return mHandler != null;
23 | }
24 |
25 | private PtrUIHandler getHandler() {
26 | return mHandler;
27 | }
28 |
29 | public static void addHandler(PtrUIHandlerHolder head, PtrUIHandler handler) {
30 |
31 | if (null == handler) {
32 | return;
33 | }
34 | if (head == null) {
35 | return;
36 | }
37 | if (null == head.mHandler) {
38 | head.mHandler = handler;
39 | return;
40 | }
41 |
42 | PtrUIHandlerHolder current = head;
43 | for (; ; current = current.mNext) {
44 |
45 | // duplicated
46 | if (current.contains(handler)) {
47 | return;
48 | }
49 | if (current.mNext == null) {
50 | break;
51 | }
52 | }
53 |
54 | PtrUIHandlerHolder newHolder = new PtrUIHandlerHolder();
55 | newHolder.mHandler = handler;
56 | current.mNext = newHolder;
57 | }
58 |
59 | public static PtrUIHandlerHolder create() {
60 | return new PtrUIHandlerHolder();
61 | }
62 |
63 | public static PtrUIHandlerHolder removeHandler(PtrUIHandlerHolder head, PtrUIHandler handler) {
64 | if (head == null || handler == null || null == head.mHandler) {
65 | return head;
66 | }
67 |
68 | PtrUIHandlerHolder current = head;
69 | PtrUIHandlerHolder pre = null;
70 | do {
71 |
72 | // delete current: link pre to next, unlink next from current;
73 | // pre will no change, current move to next element;
74 | if (current.contains(handler)) {
75 |
76 | // current is head
77 | if (pre == null) {
78 |
79 | head = current.mNext;
80 | current.mNext = null;
81 |
82 | current = head;
83 | } else {
84 |
85 | pre.mNext = current.mNext;
86 | current.mNext = null;
87 | current = pre.mNext;
88 | }
89 | } else {
90 | pre = current;
91 | current = current.mNext;
92 | }
93 |
94 | } while (current != null);
95 |
96 | if (head == null) {
97 | head = new PtrUIHandlerHolder();
98 | }
99 | return head;
100 | }
101 |
102 | @Override
103 | public void onUIReset(PtrFrameLayout frame) {
104 | PtrUIHandlerHolder current = this;
105 | do {
106 | final PtrUIHandler handler = current.getHandler();
107 | if (null != handler) {
108 | handler.onUIReset(frame);
109 | }
110 | } while ((current = current.mNext) != null);
111 | }
112 |
113 | @Override
114 | public void onUIRefreshPrepare(PtrFrameLayout frame) {
115 | if (!hasHandler()) {
116 | return;
117 | }
118 | PtrUIHandlerHolder current = this;
119 | do {
120 | final PtrUIHandler handler = current.getHandler();
121 | if (null != handler) {
122 | handler.onUIRefreshPrepare(frame);
123 | }
124 | } while ((current = current.mNext) != null);
125 | }
126 |
127 | @Override
128 | public void onUIRefreshBegin(PtrFrameLayout frame) {
129 | PtrUIHandlerHolder current = this;
130 | do {
131 | final PtrUIHandler handler = current.getHandler();
132 | if (null != handler) {
133 | handler.onUIRefreshBegin(frame);
134 | }
135 | } while ((current = current.mNext) != null);
136 | }
137 |
138 | @Override
139 | public void onUIRefreshComplete(PtrFrameLayout frame) {
140 | PtrUIHandlerHolder current = this;
141 | do {
142 | final PtrUIHandler handler = current.getHandler();
143 | if (null != handler) {
144 | handler.onUIRefreshComplete(frame);
145 | }
146 | } while ((current = current.mNext) != null);
147 | }
148 |
149 | @Override
150 | public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) {
151 | PtrUIHandlerHolder current = this;
152 | do {
153 | final PtrUIHandler handler = current.getHandler();
154 | if (null != handler) {
155 | handler.onUIPositionChange(frame, isUnderTouch, status, ptrIndicator);
156 | }
157 | } while ((current = current.mNext) != null);
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/app/src/main/java/in/srain/cube/views/ptr/PtrUIHandlerHook.java:
--------------------------------------------------------------------------------
1 | package in.srain.cube.views.ptr;
2 |
3 | /**
4 | * Run a hook runnable, the runnable will run only once.
5 | * After the runnable is done, call resume to resume.
6 | * Once run, call takeover will directory call the resume action
7 | */
8 | public abstract class PtrUIHandlerHook implements Runnable {
9 |
10 | private Runnable mResumeAction;
11 | private static final byte STATUS_PREPARE = 0;
12 | private static final byte STATUS_IN_HOOK = 1;
13 | private static final byte STATUS_RESUMED = 2;
14 | private byte mStatus = STATUS_PREPARE;
15 |
16 | public void takeOver() {
17 | takeOver(null);
18 | }
19 |
20 | public void takeOver(Runnable resumeAction) {
21 | if (resumeAction != null) {
22 | mResumeAction = resumeAction;
23 | }
24 | switch (mStatus) {
25 | case STATUS_PREPARE:
26 | mStatus = STATUS_IN_HOOK;
27 | run();
28 | break;
29 | case STATUS_IN_HOOK:
30 | break;
31 | case STATUS_RESUMED:
32 | resume();
33 | break;
34 | }
35 | }
36 |
37 | public void reset() {
38 | mStatus = STATUS_PREPARE;
39 | }
40 |
41 | public void resume() {
42 | if (mResumeAction != null) {
43 | mResumeAction.run();
44 | }
45 | mStatus = STATUS_RESUMED;
46 | }
47 |
48 | /**
49 | * Hook should always have a resume action, which is hooked by this hook.
50 | *
51 | * @param runnable
52 | */
53 | public void setResumeAction(Runnable runnable) {
54 | mResumeAction = runnable;
55 | }
56 | }
--------------------------------------------------------------------------------
/app/src/main/java/in/srain/cube/views/ptr/header/MaterialHeader.java:
--------------------------------------------------------------------------------
1 | package in.srain.cube.views.ptr.header;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Rect;
7 | import android.graphics.drawable.Drawable;
8 | import android.util.AttributeSet;
9 | import android.view.View;
10 | import android.view.animation.Animation;
11 | import android.view.animation.Transformation;
12 | import in.srain.cube.views.ptr.PtrFrameLayout;
13 | import in.srain.cube.views.ptr.PtrUIHandler;
14 | import in.srain.cube.views.ptr.PtrUIHandlerHook;
15 | import in.srain.cube.views.ptr.indicator.PtrIndicator;
16 |
17 | public class MaterialHeader extends View implements PtrUIHandler {
18 |
19 | private MaterialProgressDrawable mDrawable;
20 | private float mScale = 1f;
21 | private PtrFrameLayout mPtrFrameLayout;
22 |
23 | private Animation mScaleAnimation = new Animation() {
24 | @Override
25 | public void applyTransformation(float interpolatedTime, Transformation t) {
26 | mScale = 1f - interpolatedTime;
27 | mDrawable.setAlpha((int) (255 * mScale));
28 | invalidate();
29 | }
30 | };
31 |
32 | public MaterialHeader(Context context) {
33 | super(context);
34 | initView();
35 | }
36 |
37 | public MaterialHeader(Context context, AttributeSet attrs) {
38 | super(context, attrs);
39 | initView();
40 | }
41 |
42 | public MaterialHeader(Context context, AttributeSet attrs, int defStyleAttr) {
43 | super(context, attrs, defStyleAttr);
44 | initView();
45 | }
46 |
47 | public void setPtrFrameLayout(PtrFrameLayout layout) {
48 |
49 | final PtrUIHandlerHook mPtrUIHandlerHook = new PtrUIHandlerHook() {
50 | @Override
51 | public void run() {
52 | startAnimation(mScaleAnimation);
53 | }
54 | };
55 |
56 | mScaleAnimation.setDuration(200);
57 | mScaleAnimation.setAnimationListener(new Animation.AnimationListener() {
58 | @Override
59 | public void onAnimationStart(Animation animation) {
60 |
61 | }
62 |
63 | @Override
64 | public void onAnimationEnd(Animation animation) {
65 | mPtrUIHandlerHook.resume();
66 | }
67 |
68 | @Override
69 | public void onAnimationRepeat(Animation animation) {
70 |
71 | }
72 | });
73 |
74 | mPtrFrameLayout = layout;
75 | mPtrFrameLayout.setRefreshCompleteHook(mPtrUIHandlerHook);
76 | }
77 |
78 | private void initView() {
79 | mDrawable = new MaterialProgressDrawable(getContext(), this);
80 | mDrawable.setBackgroundColor(Color.WHITE);
81 | mDrawable.setCallback(this);
82 | }
83 |
84 | @Override
85 | public void invalidateDrawable(Drawable dr) {
86 | if (dr == mDrawable) {
87 | invalidate();
88 | } else {
89 | super.invalidateDrawable(dr);
90 | }
91 | }
92 |
93 | public void setColorSchemeColors(int[] colors) {
94 | mDrawable.setColorSchemeColors(colors);
95 | invalidate();
96 | }
97 |
98 | @Override
99 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
100 | int height = mDrawable.getIntrinsicHeight() + getPaddingTop() + getPaddingBottom();
101 | heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
102 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
103 | }
104 |
105 | @Override
106 | protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
107 | final int size = mDrawable.getIntrinsicHeight();
108 | mDrawable.setBounds(0, 0, size, size);
109 | }
110 |
111 | @Override
112 | protected void onDraw(Canvas canvas) {
113 | final int saveCount = canvas.save();
114 | Rect rect = mDrawable.getBounds();
115 | int l = getPaddingLeft() + (getMeasuredWidth() - mDrawable.getIntrinsicWidth()) / 2;
116 | canvas.translate(l, getPaddingTop());
117 | canvas.scale(mScale, mScale, rect.exactCenterX(), rect.exactCenterY());
118 | mDrawable.draw(canvas);
119 | canvas.restoreToCount(saveCount);
120 | }
121 |
122 | /**
123 | * When the content view has reached top and refresh has been completed, view will be reset.
124 | *
125 | * @param frame
126 | */
127 | @Override
128 | public void onUIReset(PtrFrameLayout frame) {
129 | mScale = 1f;
130 | mDrawable.stop();
131 | }
132 |
133 | /**
134 | * prepare for loading
135 | *
136 | * @param frame
137 | */
138 | @Override
139 | public void onUIRefreshPrepare(PtrFrameLayout frame) {
140 | }
141 |
142 | /**
143 | * perform refreshing UI
144 | *
145 | * @param frame
146 | */
147 | @Override
148 | public void onUIRefreshBegin(PtrFrameLayout frame) {
149 | mDrawable.setAlpha(255);
150 | mDrawable.start();
151 | }
152 |
153 | /**
154 | * perform UI after refresh
155 | *
156 | * @param frame
157 | */
158 | @Override
159 | public void onUIRefreshComplete(PtrFrameLayout frame) {
160 | mDrawable.stop();
161 | }
162 |
163 | @Override
164 | public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) {
165 |
166 | float percent = Math.min(1f, ptrIndicator.getCurrentPercent());
167 |
168 | if (status == PtrFrameLayout.PTR_STATUS_PREPARE) {
169 | mDrawable.setAlpha((int) (255 * percent));
170 | mDrawable.showArrow(true);
171 |
172 | float strokeStart = ((percent) * .8f);
173 | mDrawable.setStartEndTrim(0f, Math.min(0.8f, strokeStart));
174 | mDrawable.setArrowScale(Math.min(1f, percent));
175 |
176 | // magic
177 | float rotation = (-0.25f + .4f * percent + percent * 2) * .5f;
178 | mDrawable.setProgressRotation(rotation);
179 | invalidate();
180 | }
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/app/src/main/java/in/srain/cube/views/ptr/header/StoreHouseBarItem.java:
--------------------------------------------------------------------------------
1 | package in.srain.cube.views.ptr.header;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.graphics.PointF;
6 | import android.view.animation.Animation;
7 | import android.view.animation.Transformation;
8 |
9 | import java.util.Random;
10 |
11 | /**
12 | * Created by srain on 11/6/14.
13 | */
14 | public class StoreHouseBarItem extends Animation {
15 |
16 | public PointF midPoint;
17 | public float translationX;
18 | public int index;
19 |
20 | private final Paint mPaint = new Paint();
21 | private float mFromAlpha = 1.0f;
22 | private float mToAlpha = 0.4f;
23 | private PointF mCStartPoint;
24 | private PointF mCEndPoint;
25 |
26 | public StoreHouseBarItem(int index, PointF start, PointF end, int color, int lineWidth) {
27 | this.index = index;
28 |
29 | midPoint = new PointF((start.x + end.x) / 2, (start.y + end.y) / 2);
30 |
31 | mCStartPoint = new PointF(start.x - midPoint.x, start.y - midPoint.y);
32 | mCEndPoint = new PointF(end.x - midPoint.x, end.y - midPoint.y);
33 |
34 | setColor(color);
35 | setLineWidth(lineWidth);
36 | mPaint.setAntiAlias(true);
37 | mPaint.setStyle(Paint.Style.STROKE);
38 | }
39 |
40 | public void setLineWidth(int width) {
41 | mPaint.setStrokeWidth(width);
42 | }
43 |
44 | public void setColor(int color) {
45 | mPaint.setColor(color);
46 | }
47 |
48 | public void resetPosition(int horizontalRandomness) {
49 | Random random = new Random();
50 | int randomNumber = -random.nextInt(horizontalRandomness) + horizontalRandomness;
51 | translationX = randomNumber;
52 | }
53 |
54 | @Override
55 | protected void applyTransformation(float interpolatedTime, Transformation t) {
56 | float alpha = mFromAlpha;
57 | alpha = alpha + ((mToAlpha - alpha) * interpolatedTime);
58 | setAlpha(alpha);
59 | }
60 |
61 | public void start(float fromAlpha, float toAlpha) {
62 | mFromAlpha = fromAlpha;
63 | mToAlpha = toAlpha;
64 | super.start();
65 | }
66 |
67 | public void setAlpha(float alpha) {
68 | mPaint.setAlpha((int) (alpha * 255));
69 | }
70 |
71 | public void draw(Canvas canvas) {
72 | canvas.drawLine(mCStartPoint.x, mCStartPoint.y, mCEndPoint.x, mCEndPoint.y, mPaint);
73 | }
74 | }
--------------------------------------------------------------------------------
/app/src/main/java/in/srain/cube/views/ptr/indicator/PtrIndicator.java:
--------------------------------------------------------------------------------
1 | package in.srain.cube.views.ptr.indicator;
2 |
3 | import android.graphics.PointF;
4 |
5 | public class PtrIndicator {
6 |
7 | public final static int POS_START = 0;
8 | protected int mOffsetToRefresh = 0;
9 | private PointF mPtLastMove = new PointF();
10 | private float mOffsetX;
11 | private float mOffsetY;
12 | private int mCurrentPos = 0;
13 | private int mLastPos = 0;
14 | private int mHeaderHeight;
15 | private int mPressedPos = 0;
16 |
17 | private float mRatioOfHeaderHeightToRefresh = 1.2f;
18 | private float mResistance = 1.7f;
19 | private boolean mIsUnderTouch = false;
20 | private int mOffsetToKeepHeaderWhileLoading = -1;
21 | // record the refresh complete position
22 | private int mRefreshCompleteY = 0;
23 |
24 | public boolean isUnderTouch() {
25 | return mIsUnderTouch;
26 | }
27 |
28 | public float getResistance() {
29 | return mResistance;
30 | }
31 |
32 | public void setResistance(float resistance) {
33 | mResistance = resistance;
34 | }
35 |
36 | public void onRelease() {
37 | mIsUnderTouch = false;
38 | }
39 |
40 | public void onUIRefreshComplete() {
41 | mRefreshCompleteY = mCurrentPos;
42 | }
43 |
44 | public boolean goDownCrossFinishPosition() {
45 | return mCurrentPos >= mRefreshCompleteY;
46 | }
47 |
48 | protected void processOnMove(float currentX, float currentY, float offsetX, float offsetY) {
49 | setOffset(offsetX, offsetY / mResistance);
50 | }
51 |
52 | public void setRatioOfHeaderHeightToRefresh(float ratio) {
53 | mRatioOfHeaderHeightToRefresh = ratio;
54 | mOffsetToRefresh = (int) (mHeaderHeight * ratio);
55 | }
56 |
57 | public float getRatioOfHeaderToHeightRefresh() {
58 | return mRatioOfHeaderHeightToRefresh;
59 | }
60 |
61 | public int getOffsetToRefresh() {
62 | return mOffsetToRefresh;
63 | }
64 |
65 | public void setOffsetToRefresh(int offset) {
66 | mRatioOfHeaderHeightToRefresh = mHeaderHeight * 1f / offset;
67 | mOffsetToRefresh = offset;
68 | }
69 |
70 | public void onPressDown(float x, float y) {
71 | mIsUnderTouch = true;
72 | mPressedPos = mCurrentPos;
73 | mPtLastMove.set(x, y);
74 | }
75 |
76 | public final void onMove(float x, float y) {
77 | float offsetX = x - mPtLastMove.x;
78 | float offsetY = (y - mPtLastMove.y);
79 | processOnMove(x, y, offsetX, offsetY);
80 | mPtLastMove.set(x, y);
81 | }
82 |
83 | protected void setOffset(float x, float y) {
84 | mOffsetX = x;
85 | mOffsetY = y;
86 | }
87 |
88 | public float getOffsetX() {
89 | return mOffsetX;
90 | }
91 |
92 | public float getOffsetY() {
93 | return mOffsetY;
94 | }
95 |
96 | public int getLastPosY() {
97 | return mLastPos;
98 | }
99 |
100 | public int getCurrentPosY() {
101 | return mCurrentPos;
102 | }
103 |
104 | /**
105 | * Update current position before update the UI
106 | */
107 | public final void setCurrentPos(int current) {
108 | mLastPos = mCurrentPos;
109 | mCurrentPos = current;
110 | onUpdatePos(current, mLastPos);
111 | }
112 |
113 | protected void onUpdatePos(int current, int last) {
114 |
115 | }
116 |
117 | public int getHeaderHeight() {
118 | return mHeaderHeight;
119 | }
120 |
121 | public void setHeaderHeight(int height) {
122 | mHeaderHeight = height;
123 | updateHeight();
124 | }
125 |
126 | protected void updateHeight() {
127 | mOffsetToRefresh = (int) (mRatioOfHeaderHeightToRefresh * mHeaderHeight);
128 | }
129 |
130 | public void convertFrom(PtrIndicator ptrSlider) {
131 | mCurrentPos = ptrSlider.mCurrentPos;
132 | mLastPos = ptrSlider.mLastPos;
133 | mHeaderHeight = ptrSlider.mHeaderHeight;
134 | }
135 |
136 | public boolean hasLeftStartPosition() {
137 | return mCurrentPos > POS_START;
138 | }
139 |
140 | public boolean hasJustLeftStartPosition() {
141 | return mLastPos == POS_START && hasLeftStartPosition();
142 | }
143 |
144 | public boolean hasJustBackToStartPosition() {
145 | return mLastPos != POS_START && isInStartPosition();
146 | }
147 |
148 | public boolean isOverOffsetToRefresh() {
149 | return mCurrentPos >= getOffsetToRefresh();
150 | }
151 |
152 | public boolean hasMovedAfterPressedDown() {
153 | return mCurrentPos != mPressedPos;
154 | }
155 |
156 | public boolean isInStartPosition() {
157 | return mCurrentPos == POS_START;
158 | }
159 |
160 | public boolean crossRefreshLineFromTopToBottom() {
161 | return mLastPos < getOffsetToRefresh() && mCurrentPos >= getOffsetToRefresh();
162 | }
163 |
164 | public boolean hasJustReachedHeaderHeightFromTopToBottom() {
165 | return mLastPos < mHeaderHeight && mCurrentPos >= mHeaderHeight;
166 | }
167 |
168 | public boolean isOverOffsetToKeepHeaderWhileLoading() {
169 | return mCurrentPos > getOffsetToKeepHeaderWhileLoading();
170 | }
171 |
172 | public void setOffsetToKeepHeaderWhileLoading(int offset) {
173 | mOffsetToKeepHeaderWhileLoading = offset;
174 | }
175 |
176 | public int getOffsetToKeepHeaderWhileLoading() {
177 | return mOffsetToKeepHeaderWhileLoading >= 0 ? mOffsetToKeepHeaderWhileLoading : mHeaderHeight;
178 | }
179 |
180 | public boolean isAlreadyHere(int to) {
181 | return mCurrentPos == to;
182 | }
183 |
184 | public float getLastPercent() {
185 | final float oldPercent = mHeaderHeight == 0 ? 0 : mLastPos * 1f / mHeaderHeight;
186 | return oldPercent;
187 | }
188 |
189 | public float getCurrentPercent() {
190 | final float currentPercent = mHeaderHeight == 0 ? 0 : mCurrentPos * 1f / mHeaderHeight;
191 | return currentPercent;
192 | }
193 |
194 | public boolean willOverTop(int to) {
195 | return to < POS_START;
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/app/src/main/java/in/srain/cube/views/ptr/indicator/PtrTensionIndicator.java:
--------------------------------------------------------------------------------
1 | package in.srain.cube.views.ptr.indicator;
2 |
3 | public class PtrTensionIndicator extends PtrIndicator {
4 |
5 | private float DRAG_RATE = 0.5f;
6 | private float mDownY;
7 | private float mDownPos;
8 | private float mOneHeight = 0;
9 |
10 | private float mCurrentDragPercent;
11 |
12 | private int mReleasePos;
13 | private float mReleasePercent = -1;
14 |
15 | @Override
16 | public void onPressDown(float x, float y) {
17 | super.onPressDown(x, y);
18 | mDownY = y;
19 | mDownPos = getCurrentPosY();
20 | }
21 |
22 | @Override
23 | public void onRelease() {
24 | super.onRelease();
25 | mReleasePos = getCurrentPosY();
26 | mReleasePercent = mCurrentDragPercent;
27 | }
28 |
29 | @Override
30 | public void onUIRefreshComplete() {
31 | mReleasePos = getCurrentPosY();
32 | mReleasePercent = getOverDragPercent();
33 | }
34 |
35 | @Override
36 | public void setHeaderHeight(int height) {
37 | super.setHeaderHeight(height);
38 | mOneHeight = height * 4f / 5;
39 | }
40 |
41 | @Override
42 | protected void processOnMove(float currentX, float currentY, float offsetX, float offsetY) {
43 |
44 | if (currentY < mDownY) {
45 | super.processOnMove(currentX, currentY, offsetX, offsetY);
46 | return;
47 | }
48 |
49 | // distance from top
50 | final float scrollTop = (currentY - mDownY) * DRAG_RATE + mDownPos;
51 | final float currentDragPercent = scrollTop / mOneHeight;
52 |
53 | if (currentDragPercent < 0) {
54 | setOffset(offsetX, 0);
55 | return;
56 | }
57 |
58 | mCurrentDragPercent = currentDragPercent;
59 |
60 | // 0 ~ 1
61 | float boundedDragPercent = Math.min(1f, Math.abs(currentDragPercent));
62 | float extraOS = scrollTop - mOneHeight;
63 |
64 | // 0 ~ 2
65 | // if extraOS lower than 0, which means scrollTop lower than onHeight, tensionSlingshotPercent will be 0.
66 | float tensionSlingshotPercent = Math.max(0, Math.min(extraOS, mOneHeight * 2) / mOneHeight);
67 |
68 | float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow((tensionSlingshotPercent / 4), 2)) * 2f;
69 | float extraMove = (mOneHeight) * tensionPercent / 2;
70 | int targetY = (int) ((mOneHeight * boundedDragPercent) + extraMove);
71 | int change = targetY - getCurrentPosY();
72 |
73 | setOffset(currentX, change);
74 | }
75 |
76 | private float offsetToTarget(float scrollTop) {
77 |
78 | // distance from top
79 | final float currentDragPercent = scrollTop / mOneHeight;
80 |
81 | mCurrentDragPercent = currentDragPercent;
82 |
83 | // 0 ~ 1
84 | float boundedDragPercent = Math.min(1f, Math.abs(currentDragPercent));
85 | float extraOS = scrollTop - mOneHeight;
86 |
87 | // 0 ~ 2
88 | // if extraOS lower than 0, which means scrollTop lower than mOneHeight, tensionSlingshotPercent will be 0.
89 | float tensionSlingshotPercent = Math.max(0, Math.min(extraOS, mOneHeight * 2) / mOneHeight);
90 |
91 | float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow((tensionSlingshotPercent / 4), 2)) * 2f;
92 | float extraMove = (mOneHeight) * tensionPercent / 2;
93 | int targetY = (int) ((mOneHeight * boundedDragPercent) + extraMove);
94 |
95 | return 0;
96 | }
97 |
98 | @Override
99 | public int getOffsetToKeepHeaderWhileLoading() {
100 | return getOffsetToRefresh();
101 | }
102 |
103 | @Override
104 | public int getOffsetToRefresh() {
105 | return (int) mOneHeight;
106 | }
107 |
108 | public float getOverDragPercent() {
109 | if (isUnderTouch()) {
110 | return mCurrentDragPercent;
111 | } else {
112 | if (mReleasePercent <= 0) {
113 | return 1.0f * getCurrentPosY() / getOffsetToKeepHeaderWhileLoading();
114 | }
115 | // after release
116 | return mReleasePercent * getCurrentPosY() / mReleasePos;
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/app/src/main/java/in/srain/cube/views/ptr/util/PtrLocalDisplay.java:
--------------------------------------------------------------------------------
1 | package in.srain.cube.views.ptr.util;
2 |
3 | import android.content.Context;
4 | import android.util.DisplayMetrics;
5 | import android.view.View;
6 | import android.view.WindowManager;
7 |
8 | public class PtrLocalDisplay {
9 |
10 | public static int SCREEN_WIDTH_PIXELS;
11 | public static int SCREEN_HEIGHT_PIXELS;
12 | public static float SCREEN_DENSITY;
13 | public static int SCREEN_WIDTH_DP;
14 | public static int SCREEN_HEIGHT_DP;
15 |
16 | public static void init(Context context) {
17 | if (context == null) {
18 | return;
19 | }
20 | DisplayMetrics dm = new DisplayMetrics();
21 | WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
22 | wm.getDefaultDisplay().getMetrics(dm);
23 | SCREEN_WIDTH_PIXELS = dm.widthPixels;
24 | SCREEN_HEIGHT_PIXELS = dm.heightPixels;
25 | SCREEN_DENSITY = dm.density;
26 | SCREEN_WIDTH_DP = (int) (SCREEN_WIDTH_PIXELS / dm.density);
27 | SCREEN_HEIGHT_DP = (int) (SCREEN_HEIGHT_PIXELS / dm.density);
28 | }
29 |
30 | public static int dp2px(float dp) {
31 | final float scale = SCREEN_DENSITY;
32 | return (int) (dp * scale + 0.5f);
33 | }
34 |
35 | public static int designedDP2px(float designedDp) {
36 | if (SCREEN_WIDTH_DP != 320) {
37 | designedDp = designedDp * SCREEN_WIDTH_DP / 320f;
38 | }
39 | return dp2px(designedDp);
40 | }
41 |
42 | public static void setPadding(final View view, float left, float top, float right, float bottom) {
43 | view.setPadding(designedDP2px(left), dp2px(top), designedDP2px(right), dp2px(bottom));
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/se/emilsjolander/stickylistheaders/CheckableWrapperView.java:
--------------------------------------------------------------------------------
1 | package se.emilsjolander.stickylistheaders;
2 |
3 | import android.content.Context;
4 | import android.widget.Checkable;
5 |
6 | /**
7 | * A WrapperView that implements the checkable interface
8 | *
9 | * @author Emil Sjölander
10 | */
11 | class CheckableWrapperView extends WrapperView implements Checkable {
12 |
13 | public CheckableWrapperView(final Context context) {
14 | super(context);
15 | }
16 |
17 | @Override
18 | public boolean isChecked() {
19 | return ((Checkable) mItem).isChecked();
20 | }
21 |
22 | @Override
23 | public void setChecked(final boolean checked) {
24 | ((Checkable) mItem).setChecked(checked);
25 | }
26 |
27 | @Override
28 | public void toggle() {
29 | setChecked(!isChecked());
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/se/emilsjolander/stickylistheaders/DistinctMultiHashMap.java:
--------------------------------------------------------------------------------
1 | package se.emilsjolander.stickylistheaders;
2 |
3 | import java.util.ArrayList;
4 | import java.util.LinkedHashMap;
5 | import java.util.List;
6 | import java.util.Map;
7 | import java.util.Set;
8 |
9 | /**
10 | * a hash map can maintain an one-to-many relationship which the value only belongs to one “one” part
11 | * and the map also support getKey by value quickly
12 | *
13 | * @author lsjwzh
14 | */
15 | class DistinctMultiHashMap {
16 | private IDMapper mIDMapper;
17 |
18 | interface IDMapper{
19 | public Object keyToKeyId(TKey key);
20 | public TKey keyIdToKey(Object keyId);
21 | public Object valueToValueId(TItemValue value);
22 | public TItemValue valueIdToValue(Object valueId);
23 | }
24 |
25 | LinkedHashMap