diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
+
+
@@ -29,6 +31,7 @@
+
+
+
@@ -29,6 +31,7 @@
+
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
index c6d3e33..7e502f2 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
@@ -1,7 +1,11 @@
package com.casic.birmm.hxrq.mvp.view;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
public interface IFaceLoginView {
- void obtainFaceLoginData(FaceLoginResultBean resultBean);
+ void showProgress();
+
+ void hideProgress();
+
+ void obtainFaceLoginData(FaceResultBean resultBean);
}
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
index c6d3e33..7e502f2 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
@@ -1,7 +1,11 @@
package com.casic.birmm.hxrq.mvp.view;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
public interface IFaceLoginView {
- void obtainFaceLoginData(FaceLoginResultBean resultBean);
+ void showProgress();
+
+ void hideProgress();
+
+ void obtainFaceLoginData(FaceResultBean resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
index c9783cd..fe666b1 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
@@ -3,6 +3,8 @@
import com.casic.birmm.hxrq.bean.LoginResultBean;
public interface ILoginView {
+ void showProgress();
+
void hideProgress();
void obtainLoginResult(LoginResultBean resultBean);
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
index c6d3e33..7e502f2 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
@@ -1,7 +1,11 @@
package com.casic.birmm.hxrq.mvp.view;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
public interface IFaceLoginView {
- void obtainFaceLoginData(FaceLoginResultBean resultBean);
+ void showProgress();
+
+ void hideProgress();
+
+ void obtainFaceLoginData(FaceResultBean resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
index c9783cd..fe666b1 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
@@ -3,6 +3,8 @@
import com.casic.birmm.hxrq.bean.LoginResultBean;
public interface ILoginView {
+ void showProgress();
+
void hideProgress();
void obtainLoginResult(LoginResultBean resultBean);
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
index 4e8821e..4003e26 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
@@ -3,5 +3,9 @@
import com.casic.birmm.hxrq.bean.QrCodeBean;
public interface IQrCodeDataView {
+ void showProgress();
+
+ void hideProgress();
+
void obtainQrCodeData(QrCodeBean userBean);
}
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
index c6d3e33..7e502f2 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
@@ -1,7 +1,11 @@
package com.casic.birmm.hxrq.mvp.view;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
public interface IFaceLoginView {
- void obtainFaceLoginData(FaceLoginResultBean resultBean);
+ void showProgress();
+
+ void hideProgress();
+
+ void obtainFaceLoginData(FaceResultBean resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
index c9783cd..fe666b1 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
@@ -3,6 +3,8 @@
import com.casic.birmm.hxrq.bean.LoginResultBean;
public interface ILoginView {
+ void showProgress();
+
void hideProgress();
void obtainLoginResult(LoginResultBean resultBean);
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
index 4e8821e..4003e26 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
@@ -3,5 +3,9 @@
import com.casic.birmm.hxrq.bean.QrCodeBean;
public interface IQrCodeDataView {
+ void showProgress();
+
+ void hideProgress();
+
void obtainQrCodeData(QrCodeBean userBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
new file mode 100644
index 0000000..4109e3c
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
@@ -0,0 +1,184 @@
+package com.casic.birmm.hxrq.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.ImageFormat;
+import android.hardware.Camera;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import androidx.annotation.NonNull;
+
+import com.casic.birmm.hxrq.R;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.utils.ImageHelper;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Stack;
+
+import butterknife.BindView;
+
+public class FacePreViewActivity extends BaseActivity implements Camera.PreviewCallback {
+
+ private static final int preViewWidth = 720;
+ private static final int preViewHeight = 1280;
+ @BindView(R.id.surfaceView)
+ SurfaceView surfaceView;
+ private SurfaceHolder mSurfaceHolder;
+ private Camera mCamera;
+ private ImageHelper imageHelper;
+ private Stack bitmapStack;
+ private boolean isCanLogin = true;
+
+ @Override
+ public int initLayoutView() {
+ return R.layout.activity_face;
+ }
+
+ @Override
+ protected void setupTopBarLayout() {
+
+ }
+
+ @Override
+ public void initData() {
+ imageHelper = new ImageHelper(this);
+ bitmapStack = new Stack<>();
+ }
+
+ @Override
+ public void initEvent() {
+ // 绑定SurfaceView,取得SurfaceHolder对象
+ mSurfaceHolder = surfaceView.getHolder();
+ mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(@NonNull SurfaceHolder holder) {
+ if (mCamera == null) {
+ //打开相机
+ openCamera();
+ }
+ try {
+ //预览画面
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ //开始预览
+ mCamera.startPreview();
+ }
+
+ @Override
+ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
+
+ }
+
+ @Override
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+ releaseCamera(); //释放相机资源
+ }
+ });
+ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置
+ }
+
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ camera.addCallbackBuffer(data);
+ Camera.Size size = camera.getParameters().getPreviewSize();//必须是相机支持的预览尺寸,否则颜色YUV空间会错位
+ Bitmap originBitmap = imageHelper.nv21ToBitmap(data, size.width, size.height);
+ //要使用Android内置的人脸识别,需要将Bitmap对象转为RGB_565格式,否则无法识别
+// Bitmap faceDetectorBitmap = originBitmap.copy(Bitmap.Config.RGB_565, true);
+// FaceDetector.Face[] faces = new FaceDetector.Face[1];
+// FaceDetector faceDetector = new FaceDetector(faceDetectorBitmap.getWidth(), faceDetectorBitmap.getHeight(), 1);
+// int faceSum = faceDetector.findFaces(faceDetectorBitmap, faces);
+// if (faceSum == 1) {
+ bitmapStack.push(originBitmap);
+ if (bitmapStack.size() >= 5) {//当栈里有5张bitmap之后才开始识别
+ if (isCanLogin) {
+ isCanLogin = false;
+ Bitmap bitmap = bitmapStack.pop();
+ Intent intent = new Intent();
+ intent.putExtra("imageToBase64", ImageHelper.imageToBase64(bitmap));
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ } else {
+ finish();
+ }
+ }
+// } else {
+// Log.d(TAG, "detectorFace: 未检测到人脸");
+// }
+ }
+
+ /**
+ * 打开相机
+ */
+ private void openCamera() {
+ try {
+ mCamera = Camera.open(1);
+ initParameters(mCamera); //初始化相机配置信息
+ mCamera.setPreviewCallback(this);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 初始化相机属性
+ */
+ private void initParameters(Camera camera) {
+ try {
+ Camera.Parameters mParameters = camera.getParameters();
+ mParameters.setPreviewFormat(ImageFormat.NV21); //设置预览图片的格式
+ //获取与指定宽高相等或最接近的尺寸
+ //设置预览尺寸
+ Camera.Size bestPreviewSize = obtainBestSize(preViewWidth, preViewHeight, mParameters.getSupportedPreviewSizes());
+ mParameters.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height);
+ //设置保存图片尺寸
+// Camera.Size bestPicSize = obtainBestSize(picWidth, picHeight, mParameters.getSupportedPictureSizes());
+// mParameters.setPictureSize(bestPicSize.width, bestPicSize.height);
+ //对焦模式
+ mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ camera.setDisplayOrientation(90);
+ camera.setParameters(mParameters);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 获取最合适的尺寸
+ */
+ private Camera.Size obtainBestSize(int targetWidth, int targetHeight, List sizeList) {
+ Camera.Size bestSize = null;
+ int targetRatio = targetHeight / targetWidth;//目标大小的宽高比
+ int minDiff = targetRatio;
+
+ for (Camera.Size size : sizeList) {
+ if (size.width == targetHeight && size.height == targetWidth) {
+ bestSize = size;
+ break;
+ }
+ int supportedRatio = (size.width / size.height);
+ if (Math.abs(supportedRatio - targetRatio) < minDiff) {
+ minDiff = Math.abs(supportedRatio - targetRatio);
+ bestSize = size;
+ }
+ }
+ return bestSize;
+ }
+
+ /**
+ * 释放相机资源
+ */
+ private void releaseCamera() {
+ if (mCamera != null) {
+ mCamera.stopPreview();
+ mCamera.setPreviewCallback(null);
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
index c6d3e33..7e502f2 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
@@ -1,7 +1,11 @@
package com.casic.birmm.hxrq.mvp.view;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
public interface IFaceLoginView {
- void obtainFaceLoginData(FaceLoginResultBean resultBean);
+ void showProgress();
+
+ void hideProgress();
+
+ void obtainFaceLoginData(FaceResultBean resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
index c9783cd..fe666b1 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
@@ -3,6 +3,8 @@
import com.casic.birmm.hxrq.bean.LoginResultBean;
public interface ILoginView {
+ void showProgress();
+
void hideProgress();
void obtainLoginResult(LoginResultBean resultBean);
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
index 4e8821e..4003e26 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
@@ -3,5 +3,9 @@
import com.casic.birmm.hxrq.bean.QrCodeBean;
public interface IQrCodeDataView {
+ void showProgress();
+
+ void hideProgress();
+
void obtainQrCodeData(QrCodeBean userBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
new file mode 100644
index 0000000..4109e3c
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
@@ -0,0 +1,184 @@
+package com.casic.birmm.hxrq.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.ImageFormat;
+import android.hardware.Camera;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import androidx.annotation.NonNull;
+
+import com.casic.birmm.hxrq.R;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.utils.ImageHelper;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Stack;
+
+import butterknife.BindView;
+
+public class FacePreViewActivity extends BaseActivity implements Camera.PreviewCallback {
+
+ private static final int preViewWidth = 720;
+ private static final int preViewHeight = 1280;
+ @BindView(R.id.surfaceView)
+ SurfaceView surfaceView;
+ private SurfaceHolder mSurfaceHolder;
+ private Camera mCamera;
+ private ImageHelper imageHelper;
+ private Stack bitmapStack;
+ private boolean isCanLogin = true;
+
+ @Override
+ public int initLayoutView() {
+ return R.layout.activity_face;
+ }
+
+ @Override
+ protected void setupTopBarLayout() {
+
+ }
+
+ @Override
+ public void initData() {
+ imageHelper = new ImageHelper(this);
+ bitmapStack = new Stack<>();
+ }
+
+ @Override
+ public void initEvent() {
+ // 绑定SurfaceView,取得SurfaceHolder对象
+ mSurfaceHolder = surfaceView.getHolder();
+ mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(@NonNull SurfaceHolder holder) {
+ if (mCamera == null) {
+ //打开相机
+ openCamera();
+ }
+ try {
+ //预览画面
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ //开始预览
+ mCamera.startPreview();
+ }
+
+ @Override
+ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
+
+ }
+
+ @Override
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+ releaseCamera(); //释放相机资源
+ }
+ });
+ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置
+ }
+
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ camera.addCallbackBuffer(data);
+ Camera.Size size = camera.getParameters().getPreviewSize();//必须是相机支持的预览尺寸,否则颜色YUV空间会错位
+ Bitmap originBitmap = imageHelper.nv21ToBitmap(data, size.width, size.height);
+ //要使用Android内置的人脸识别,需要将Bitmap对象转为RGB_565格式,否则无法识别
+// Bitmap faceDetectorBitmap = originBitmap.copy(Bitmap.Config.RGB_565, true);
+// FaceDetector.Face[] faces = new FaceDetector.Face[1];
+// FaceDetector faceDetector = new FaceDetector(faceDetectorBitmap.getWidth(), faceDetectorBitmap.getHeight(), 1);
+// int faceSum = faceDetector.findFaces(faceDetectorBitmap, faces);
+// if (faceSum == 1) {
+ bitmapStack.push(originBitmap);
+ if (bitmapStack.size() >= 5) {//当栈里有5张bitmap之后才开始识别
+ if (isCanLogin) {
+ isCanLogin = false;
+ Bitmap bitmap = bitmapStack.pop();
+ Intent intent = new Intent();
+ intent.putExtra("imageToBase64", ImageHelper.imageToBase64(bitmap));
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ } else {
+ finish();
+ }
+ }
+// } else {
+// Log.d(TAG, "detectorFace: 未检测到人脸");
+// }
+ }
+
+ /**
+ * 打开相机
+ */
+ private void openCamera() {
+ try {
+ mCamera = Camera.open(1);
+ initParameters(mCamera); //初始化相机配置信息
+ mCamera.setPreviewCallback(this);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 初始化相机属性
+ */
+ private void initParameters(Camera camera) {
+ try {
+ Camera.Parameters mParameters = camera.getParameters();
+ mParameters.setPreviewFormat(ImageFormat.NV21); //设置预览图片的格式
+ //获取与指定宽高相等或最接近的尺寸
+ //设置预览尺寸
+ Camera.Size bestPreviewSize = obtainBestSize(preViewWidth, preViewHeight, mParameters.getSupportedPreviewSizes());
+ mParameters.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height);
+ //设置保存图片尺寸
+// Camera.Size bestPicSize = obtainBestSize(picWidth, picHeight, mParameters.getSupportedPictureSizes());
+// mParameters.setPictureSize(bestPicSize.width, bestPicSize.height);
+ //对焦模式
+ mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ camera.setDisplayOrientation(90);
+ camera.setParameters(mParameters);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 获取最合适的尺寸
+ */
+ private Camera.Size obtainBestSize(int targetWidth, int targetHeight, List sizeList) {
+ Camera.Size bestSize = null;
+ int targetRatio = targetHeight / targetWidth;//目标大小的宽高比
+ int minDiff = targetRatio;
+
+ for (Camera.Size size : sizeList) {
+ if (size.width == targetHeight && size.height == targetWidth) {
+ bestSize = size;
+ break;
+ }
+ int supportedRatio = (size.width / size.height);
+ if (Math.abs(supportedRatio - targetRatio) < minDiff) {
+ minDiff = Math.abs(supportedRatio - targetRatio);
+ bestSize = size;
+ }
+ }
+ return bestSize;
+ }
+
+ /**
+ * 释放相机资源
+ */
+ private void releaseCamera() {
+ if (mCamera != null) {
+ mCamera.stopPreview();
+ mCamera.setPreviewCallback(null);
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
index 98aef9d..30c26c8 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
@@ -8,14 +8,15 @@
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.casic.birmm.hxrq.R;
-import com.casic.birmm.hxrq.base.DoubleClickExitActivity;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -28,23 +29,16 @@
import com.casic.birmm.hxrq.mvp.view.IFaceLoginView;
import com.casic.birmm.hxrq.mvp.view.ILoginView;
import com.casic.birmm.hxrq.mvp.view.IQrCodeDataView;
-import com.casic.birmm.hxrq.utils.FileUtils;
-import com.casic.birmm.hxrq.utils.GlideLoadEngine;
+import com.casic.birmm.hxrq.utils.Constant;
import com.casic.birmm.hxrq.utils.RSAUtils;
import com.casic.birmm.hxrq.utils.SaveKeyValues;
-import com.casic.birmm.hxrq.utils.StringHelper;
import com.casic.birmm.hxrq.utils.TokenHelper;
import com.google.gson.Gson;
-import com.luck.picture.lib.PictureSelector;
-import com.luck.picture.lib.config.PictureConfig;
-import com.luck.picture.lib.config.PictureMimeType;
-import com.luck.picture.lib.entity.LocalMedia;
import com.qmuiteam.qmui.util.QMUIStatusBarHelper;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton;
-import java.io.File;
import java.security.PublicKey;
import butterknife.BindView;
@@ -53,15 +47,11 @@
import cn.bertsir.zbar.QrConfig;
import cn.bertsir.zbar.QrManager;
import cn.bertsir.zbar.view.ScanLineView;
-import top.zibin.luban.CompressionPredicate;
-import top.zibin.luban.Luban;
-import top.zibin.luban.OnCompressListener;
-public class LoginActivity extends DoubleClickExitActivity
- implements View.OnClickListener, IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
+public class LoginActivity extends BaseActivity implements View.OnClickListener,
+ IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
private static final String TAG = "LoginActivity";
-
@BindView(R.id.userNameView)
EditText userNameView;
@BindView(R.id.userPasswordView)
@@ -76,8 +66,8 @@
private LoginPresenterImpl loginPresenter;
private QrCodePresenterImpl qrCodePresenter;
private FaceLoginPresenterImpl faceLoginPresenter;
- private String userName;
- private String userPassword;
+ private boolean isPasswordLogin = false;
+ private String qrCode = "";
@Override
public int initLayoutView() {
@@ -86,20 +76,29 @@
@Override
protected void setupTopBarLayout() {
- //TODO 此页面无需实现
+ //设置状态栏黑色字体图标
+ QMUIStatusBarHelper.setStatusBarLightMode(this);
}
@Override
public void initData() {
- //设置状态栏黑色字体图标
- QMUIStatusBarHelper.setStatusBarLightMode(this);
-
String userName = (String) SaveKeyValues.getValue("userName", "");
String userPassword = (String) SaveKeyValues.getValue("userPassword", "");
+ userNameView.setText(userName);
+ userPasswordView.setText(userPassword);
if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) {
- userNameView.setText(userName);
- userPasswordView.setText(userPassword);
+ rememberPasswordView.setChecked(true);
+ } else {
+ rememberPasswordView.setChecked(false);
}
+ rememberPasswordView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (!isChecked) {
+ SaveKeyValues.removeKey("userPassword");
+ }
+ }
+ });
loadingDialog = new QMUITipDialog.Builder(this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
.setTipWord("登陆中,请稍后")
@@ -124,14 +123,9 @@
public void onClick(View v) {
switch (v.getId()) {
case R.id.loginButton:
- userName = userNameView.getText().toString();
- userPassword = userPasswordView.getText().toString();
- if (rememberPasswordView.isChecked()) {
- SaveKeyValues.putValue("userName", userName);
- SaveKeyValues.putValue("userPassword", userPassword);
- }
//密码登录前需要验证sid
authenticatePresenter.onReadyRetrofitRequest();
+ isPasswordLogin = true;
break;
case R.id.changeLoginModeView:
//首次登录不可用扫码,因为还未注册
@@ -169,50 +163,19 @@
}
private void captureFaceData() {
- //TODO 调相机,捕获人脸数据,并保存为文件得到路径
- PictureSelector.create(this)
- .openCamera(PictureMimeType.ofImage())
- .imageEngine(GlideLoadEngine.createGlideEngine())
- .maxSelectNum(1)
- .forResult(PictureConfig.REQUEST_CAMERA);
+ // 调相机,捕获人脸数据,并保存为文件得到路径
+ startActivityForResult(new Intent(this, FacePreViewActivity.class), Constant.FACE_DETECTOR_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
- if (requestCode == PictureConfig.REQUEST_CAMERA) {
- LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0);
- Luban.with(this)
- .load(localMedia.getRealPath())
- .ignoreBy(100)
- .setTargetDir(FileUtils.getFileDir("CompressImageFile"))
- .filter(new CompressionPredicate() {
- @Override
- public boolean apply(String path) {
- return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));
- }
- })
- .setCompressListener(new OnCompressListener() {
- @Override
- public void onStart() {
- // TODO 压缩开始前调用,可以在方法内启动 loading UI
- }
-
- @Override
- public void onSuccess(File file) {
- String imageToBase64 = StringHelper.imageToBase64(file);
-
- ImageBean imageBean = new ImageBean();
- imageBean.setImage(imageToBase64);
- faceLoginPresenter.onReadyRetrofitRequest(imageBean);
- }
-
- @Override
- public void onError(Throwable e) {
- // TODO 当压缩过程出现问题时调用
- }
- }).launch();
+ if (requestCode == Constant.FACE_DETECTOR_CODE) {
+ String imageToBase64 = data.getStringExtra("imageToBase64");
+ ImageBean imageBean = new ImageBean();
+ imageBean.setImage(imageToBase64);
+ faceLoginPresenter.onReadyRetrofitRequest(imageBean);
}
}
}
@@ -232,7 +195,7 @@
.setPlaySound(true)//是否扫描成功后bi~的声音
.setDingPath(R.raw.qrcode)//设置提示音(不设置为默认的Ding~)
.setIsOnlyCenter(true)//是否只识别框中内容(默认为全屏识别)
- .setTitleBackgroudColor(Color.parseColor("#262020"))//设置状态栏颜色
+ .setTitleBackgroudColor(R.color.black)//设置状态栏颜色
.setTitleTextColor(Color.WHITE)//设置Title文字颜色
.setScreenOrientation(QrConfig.SCREEN_PORTRAIT)//设置屏幕方式
.setScanLineStyle(ScanLineView.style_hybrid)//扫描线样式
@@ -241,8 +204,8 @@
QrManager.getInstance().init(qrConfig).startScan(this, new QrManager.OnScanResultCallback() {
@Override
public void onScanSuccess(final ScanResult result) {
-// Log.d(TAG, "扫码结果: " + result.content);
- qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), result.content);
+ qrCode = result.content;
+ authenticatePresenter.onReadyRetrofitRequest();//需要时时保持最新token,所以扫码登录之前需要获取最新token
}
});
}
@@ -254,9 +217,15 @@
@Override
public void authenticateResult(PublicKeyBean result) {
- Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
+// Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
if (result.isSuccess()) {
PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey());
+ String userName = userNameView.getText().toString();
+ String userPassword = userPasswordView.getText().toString();
+ if (rememberPasswordView.isChecked()) {
+ SaveKeyValues.putValue("userName", userName);
+ SaveKeyValues.putValue("userPassword", userPassword);
+ }
if (TextUtils.isEmpty(userName)) {
Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show();
return;
@@ -266,7 +235,6 @@
return;
}
String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey);
- Log.d(TAG, "authenticateResult: 验证成功,开始登录");
//登录并获取Token,POST请求
loginPresenter.onReadyRetrofitRequest(result.getData().getSid(), userName, dataByPublicKey);
} else {
@@ -283,11 +251,14 @@
String token = result.getData().getToken();
if (!TextUtils.isEmpty(token)) {
//获取用户信息
- Log.d(TAG, "obtainLoginResult: 获取Token成功");
TokenHelper.saveToken(token);
//验证成功登录
- startActivity(new Intent(this, MainActivity.class));
- finish();
+ if (isPasswordLogin) {
+ startActivity(new Intent(this, MainActivity.class));
+ finish();
+ } else {
+ qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), qrCode);
+ }
}
}
@@ -307,15 +278,17 @@
}
@Override
- public void obtainFaceLoginData(FaceLoginResultBean resultBean) {
-// Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
- if (resultBean.getCode() == 200) {
+ public void obtainFaceLoginData(FaceResultBean resultBean) {
+ Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
+ if (resultBean.isSuccess()) {
+ //{"code":200,"data":{"kaptcha":"","token":"9135bcb7-4f39-4b7a-a10e-555406ddb9e1"},"exceptionClazz":"","message":"登录成功","success":true}
TokenHelper.saveToken(resultBean.getData().getToken());
//验证成功登录
startActivity(new Intent(this, MainActivity.class));
finish();
} else {
- Toast.makeText(this, "无法解析人脸", Toast.LENGTH_SHORT).show();
+ //{"code":200,"data":"","exceptionClazz":"","message":"图片中没有人脸","success":false}
+ Toast.makeText(this, "人脸识别失败", Toast.LENGTH_SHORT).show();
}
}
@@ -336,5 +309,8 @@
if (qrCodePresenter != null) {
qrCodePresenter.disposeRetrofitRequest();
}
+ if (faceLoginPresenter != null) {
+ faceLoginPresenter.disposeRetrofitRequest();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
index c6d3e33..7e502f2 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
@@ -1,7 +1,11 @@
package com.casic.birmm.hxrq.mvp.view;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
public interface IFaceLoginView {
- void obtainFaceLoginData(FaceLoginResultBean resultBean);
+ void showProgress();
+
+ void hideProgress();
+
+ void obtainFaceLoginData(FaceResultBean resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
index c9783cd..fe666b1 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
@@ -3,6 +3,8 @@
import com.casic.birmm.hxrq.bean.LoginResultBean;
public interface ILoginView {
+ void showProgress();
+
void hideProgress();
void obtainLoginResult(LoginResultBean resultBean);
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
index 4e8821e..4003e26 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
@@ -3,5 +3,9 @@
import com.casic.birmm.hxrq.bean.QrCodeBean;
public interface IQrCodeDataView {
+ void showProgress();
+
+ void hideProgress();
+
void obtainQrCodeData(QrCodeBean userBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
new file mode 100644
index 0000000..4109e3c
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
@@ -0,0 +1,184 @@
+package com.casic.birmm.hxrq.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.ImageFormat;
+import android.hardware.Camera;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import androidx.annotation.NonNull;
+
+import com.casic.birmm.hxrq.R;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.utils.ImageHelper;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Stack;
+
+import butterknife.BindView;
+
+public class FacePreViewActivity extends BaseActivity implements Camera.PreviewCallback {
+
+ private static final int preViewWidth = 720;
+ private static final int preViewHeight = 1280;
+ @BindView(R.id.surfaceView)
+ SurfaceView surfaceView;
+ private SurfaceHolder mSurfaceHolder;
+ private Camera mCamera;
+ private ImageHelper imageHelper;
+ private Stack bitmapStack;
+ private boolean isCanLogin = true;
+
+ @Override
+ public int initLayoutView() {
+ return R.layout.activity_face;
+ }
+
+ @Override
+ protected void setupTopBarLayout() {
+
+ }
+
+ @Override
+ public void initData() {
+ imageHelper = new ImageHelper(this);
+ bitmapStack = new Stack<>();
+ }
+
+ @Override
+ public void initEvent() {
+ // 绑定SurfaceView,取得SurfaceHolder对象
+ mSurfaceHolder = surfaceView.getHolder();
+ mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(@NonNull SurfaceHolder holder) {
+ if (mCamera == null) {
+ //打开相机
+ openCamera();
+ }
+ try {
+ //预览画面
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ //开始预览
+ mCamera.startPreview();
+ }
+
+ @Override
+ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
+
+ }
+
+ @Override
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+ releaseCamera(); //释放相机资源
+ }
+ });
+ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置
+ }
+
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ camera.addCallbackBuffer(data);
+ Camera.Size size = camera.getParameters().getPreviewSize();//必须是相机支持的预览尺寸,否则颜色YUV空间会错位
+ Bitmap originBitmap = imageHelper.nv21ToBitmap(data, size.width, size.height);
+ //要使用Android内置的人脸识别,需要将Bitmap对象转为RGB_565格式,否则无法识别
+// Bitmap faceDetectorBitmap = originBitmap.copy(Bitmap.Config.RGB_565, true);
+// FaceDetector.Face[] faces = new FaceDetector.Face[1];
+// FaceDetector faceDetector = new FaceDetector(faceDetectorBitmap.getWidth(), faceDetectorBitmap.getHeight(), 1);
+// int faceSum = faceDetector.findFaces(faceDetectorBitmap, faces);
+// if (faceSum == 1) {
+ bitmapStack.push(originBitmap);
+ if (bitmapStack.size() >= 5) {//当栈里有5张bitmap之后才开始识别
+ if (isCanLogin) {
+ isCanLogin = false;
+ Bitmap bitmap = bitmapStack.pop();
+ Intent intent = new Intent();
+ intent.putExtra("imageToBase64", ImageHelper.imageToBase64(bitmap));
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ } else {
+ finish();
+ }
+ }
+// } else {
+// Log.d(TAG, "detectorFace: 未检测到人脸");
+// }
+ }
+
+ /**
+ * 打开相机
+ */
+ private void openCamera() {
+ try {
+ mCamera = Camera.open(1);
+ initParameters(mCamera); //初始化相机配置信息
+ mCamera.setPreviewCallback(this);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 初始化相机属性
+ */
+ private void initParameters(Camera camera) {
+ try {
+ Camera.Parameters mParameters = camera.getParameters();
+ mParameters.setPreviewFormat(ImageFormat.NV21); //设置预览图片的格式
+ //获取与指定宽高相等或最接近的尺寸
+ //设置预览尺寸
+ Camera.Size bestPreviewSize = obtainBestSize(preViewWidth, preViewHeight, mParameters.getSupportedPreviewSizes());
+ mParameters.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height);
+ //设置保存图片尺寸
+// Camera.Size bestPicSize = obtainBestSize(picWidth, picHeight, mParameters.getSupportedPictureSizes());
+// mParameters.setPictureSize(bestPicSize.width, bestPicSize.height);
+ //对焦模式
+ mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ camera.setDisplayOrientation(90);
+ camera.setParameters(mParameters);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 获取最合适的尺寸
+ */
+ private Camera.Size obtainBestSize(int targetWidth, int targetHeight, List sizeList) {
+ Camera.Size bestSize = null;
+ int targetRatio = targetHeight / targetWidth;//目标大小的宽高比
+ int minDiff = targetRatio;
+
+ for (Camera.Size size : sizeList) {
+ if (size.width == targetHeight && size.height == targetWidth) {
+ bestSize = size;
+ break;
+ }
+ int supportedRatio = (size.width / size.height);
+ if (Math.abs(supportedRatio - targetRatio) < minDiff) {
+ minDiff = Math.abs(supportedRatio - targetRatio);
+ bestSize = size;
+ }
+ }
+ return bestSize;
+ }
+
+ /**
+ * 释放相机资源
+ */
+ private void releaseCamera() {
+ if (mCamera != null) {
+ mCamera.stopPreview();
+ mCamera.setPreviewCallback(null);
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
index 98aef9d..30c26c8 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
@@ -8,14 +8,15 @@
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.casic.birmm.hxrq.R;
-import com.casic.birmm.hxrq.base.DoubleClickExitActivity;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -28,23 +29,16 @@
import com.casic.birmm.hxrq.mvp.view.IFaceLoginView;
import com.casic.birmm.hxrq.mvp.view.ILoginView;
import com.casic.birmm.hxrq.mvp.view.IQrCodeDataView;
-import com.casic.birmm.hxrq.utils.FileUtils;
-import com.casic.birmm.hxrq.utils.GlideLoadEngine;
+import com.casic.birmm.hxrq.utils.Constant;
import com.casic.birmm.hxrq.utils.RSAUtils;
import com.casic.birmm.hxrq.utils.SaveKeyValues;
-import com.casic.birmm.hxrq.utils.StringHelper;
import com.casic.birmm.hxrq.utils.TokenHelper;
import com.google.gson.Gson;
-import com.luck.picture.lib.PictureSelector;
-import com.luck.picture.lib.config.PictureConfig;
-import com.luck.picture.lib.config.PictureMimeType;
-import com.luck.picture.lib.entity.LocalMedia;
import com.qmuiteam.qmui.util.QMUIStatusBarHelper;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton;
-import java.io.File;
import java.security.PublicKey;
import butterknife.BindView;
@@ -53,15 +47,11 @@
import cn.bertsir.zbar.QrConfig;
import cn.bertsir.zbar.QrManager;
import cn.bertsir.zbar.view.ScanLineView;
-import top.zibin.luban.CompressionPredicate;
-import top.zibin.luban.Luban;
-import top.zibin.luban.OnCompressListener;
-public class LoginActivity extends DoubleClickExitActivity
- implements View.OnClickListener, IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
+public class LoginActivity extends BaseActivity implements View.OnClickListener,
+ IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
private static final String TAG = "LoginActivity";
-
@BindView(R.id.userNameView)
EditText userNameView;
@BindView(R.id.userPasswordView)
@@ -76,8 +66,8 @@
private LoginPresenterImpl loginPresenter;
private QrCodePresenterImpl qrCodePresenter;
private FaceLoginPresenterImpl faceLoginPresenter;
- private String userName;
- private String userPassword;
+ private boolean isPasswordLogin = false;
+ private String qrCode = "";
@Override
public int initLayoutView() {
@@ -86,20 +76,29 @@
@Override
protected void setupTopBarLayout() {
- //TODO 此页面无需实现
+ //设置状态栏黑色字体图标
+ QMUIStatusBarHelper.setStatusBarLightMode(this);
}
@Override
public void initData() {
- //设置状态栏黑色字体图标
- QMUIStatusBarHelper.setStatusBarLightMode(this);
-
String userName = (String) SaveKeyValues.getValue("userName", "");
String userPassword = (String) SaveKeyValues.getValue("userPassword", "");
+ userNameView.setText(userName);
+ userPasswordView.setText(userPassword);
if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) {
- userNameView.setText(userName);
- userPasswordView.setText(userPassword);
+ rememberPasswordView.setChecked(true);
+ } else {
+ rememberPasswordView.setChecked(false);
}
+ rememberPasswordView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (!isChecked) {
+ SaveKeyValues.removeKey("userPassword");
+ }
+ }
+ });
loadingDialog = new QMUITipDialog.Builder(this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
.setTipWord("登陆中,请稍后")
@@ -124,14 +123,9 @@
public void onClick(View v) {
switch (v.getId()) {
case R.id.loginButton:
- userName = userNameView.getText().toString();
- userPassword = userPasswordView.getText().toString();
- if (rememberPasswordView.isChecked()) {
- SaveKeyValues.putValue("userName", userName);
- SaveKeyValues.putValue("userPassword", userPassword);
- }
//密码登录前需要验证sid
authenticatePresenter.onReadyRetrofitRequest();
+ isPasswordLogin = true;
break;
case R.id.changeLoginModeView:
//首次登录不可用扫码,因为还未注册
@@ -169,50 +163,19 @@
}
private void captureFaceData() {
- //TODO 调相机,捕获人脸数据,并保存为文件得到路径
- PictureSelector.create(this)
- .openCamera(PictureMimeType.ofImage())
- .imageEngine(GlideLoadEngine.createGlideEngine())
- .maxSelectNum(1)
- .forResult(PictureConfig.REQUEST_CAMERA);
+ // 调相机,捕获人脸数据,并保存为文件得到路径
+ startActivityForResult(new Intent(this, FacePreViewActivity.class), Constant.FACE_DETECTOR_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
- if (requestCode == PictureConfig.REQUEST_CAMERA) {
- LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0);
- Luban.with(this)
- .load(localMedia.getRealPath())
- .ignoreBy(100)
- .setTargetDir(FileUtils.getFileDir("CompressImageFile"))
- .filter(new CompressionPredicate() {
- @Override
- public boolean apply(String path) {
- return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));
- }
- })
- .setCompressListener(new OnCompressListener() {
- @Override
- public void onStart() {
- // TODO 压缩开始前调用,可以在方法内启动 loading UI
- }
-
- @Override
- public void onSuccess(File file) {
- String imageToBase64 = StringHelper.imageToBase64(file);
-
- ImageBean imageBean = new ImageBean();
- imageBean.setImage(imageToBase64);
- faceLoginPresenter.onReadyRetrofitRequest(imageBean);
- }
-
- @Override
- public void onError(Throwable e) {
- // TODO 当压缩过程出现问题时调用
- }
- }).launch();
+ if (requestCode == Constant.FACE_DETECTOR_CODE) {
+ String imageToBase64 = data.getStringExtra("imageToBase64");
+ ImageBean imageBean = new ImageBean();
+ imageBean.setImage(imageToBase64);
+ faceLoginPresenter.onReadyRetrofitRequest(imageBean);
}
}
}
@@ -232,7 +195,7 @@
.setPlaySound(true)//是否扫描成功后bi~的声音
.setDingPath(R.raw.qrcode)//设置提示音(不设置为默认的Ding~)
.setIsOnlyCenter(true)//是否只识别框中内容(默认为全屏识别)
- .setTitleBackgroudColor(Color.parseColor("#262020"))//设置状态栏颜色
+ .setTitleBackgroudColor(R.color.black)//设置状态栏颜色
.setTitleTextColor(Color.WHITE)//设置Title文字颜色
.setScreenOrientation(QrConfig.SCREEN_PORTRAIT)//设置屏幕方式
.setScanLineStyle(ScanLineView.style_hybrid)//扫描线样式
@@ -241,8 +204,8 @@
QrManager.getInstance().init(qrConfig).startScan(this, new QrManager.OnScanResultCallback() {
@Override
public void onScanSuccess(final ScanResult result) {
-// Log.d(TAG, "扫码结果: " + result.content);
- qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), result.content);
+ qrCode = result.content;
+ authenticatePresenter.onReadyRetrofitRequest();//需要时时保持最新token,所以扫码登录之前需要获取最新token
}
});
}
@@ -254,9 +217,15 @@
@Override
public void authenticateResult(PublicKeyBean result) {
- Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
+// Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
if (result.isSuccess()) {
PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey());
+ String userName = userNameView.getText().toString();
+ String userPassword = userPasswordView.getText().toString();
+ if (rememberPasswordView.isChecked()) {
+ SaveKeyValues.putValue("userName", userName);
+ SaveKeyValues.putValue("userPassword", userPassword);
+ }
if (TextUtils.isEmpty(userName)) {
Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show();
return;
@@ -266,7 +235,6 @@
return;
}
String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey);
- Log.d(TAG, "authenticateResult: 验证成功,开始登录");
//登录并获取Token,POST请求
loginPresenter.onReadyRetrofitRequest(result.getData().getSid(), userName, dataByPublicKey);
} else {
@@ -283,11 +251,14 @@
String token = result.getData().getToken();
if (!TextUtils.isEmpty(token)) {
//获取用户信息
- Log.d(TAG, "obtainLoginResult: 获取Token成功");
TokenHelper.saveToken(token);
//验证成功登录
- startActivity(new Intent(this, MainActivity.class));
- finish();
+ if (isPasswordLogin) {
+ startActivity(new Intent(this, MainActivity.class));
+ finish();
+ } else {
+ qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), qrCode);
+ }
}
}
@@ -307,15 +278,17 @@
}
@Override
- public void obtainFaceLoginData(FaceLoginResultBean resultBean) {
-// Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
- if (resultBean.getCode() == 200) {
+ public void obtainFaceLoginData(FaceResultBean resultBean) {
+ Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
+ if (resultBean.isSuccess()) {
+ //{"code":200,"data":{"kaptcha":"","token":"9135bcb7-4f39-4b7a-a10e-555406ddb9e1"},"exceptionClazz":"","message":"登录成功","success":true}
TokenHelper.saveToken(resultBean.getData().getToken());
//验证成功登录
startActivity(new Intent(this, MainActivity.class));
finish();
} else {
- Toast.makeText(this, "无法解析人脸", Toast.LENGTH_SHORT).show();
+ //{"code":200,"data":"","exceptionClazz":"","message":"图片中没有人脸","success":false}
+ Toast.makeText(this, "人脸识别失败", Toast.LENGTH_SHORT).show();
}
}
@@ -336,5 +309,8 @@
if (qrCodePresenter != null) {
qrCodePresenter.disposeRetrofitRequest();
}
+ if (faceLoginPresenter != null) {
+ faceLoginPresenter.disposeRetrofitRequest();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
index e8e9b75..759a94d 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
@@ -9,4 +9,5 @@
Manifest.permission.WRITE_EXTERNAL_STORAGE};
public static final int PERMISSIONS_CODE = 999;
+ public static final int FACE_DETECTOR_CODE = 998;
}
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
index c6d3e33..7e502f2 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
@@ -1,7 +1,11 @@
package com.casic.birmm.hxrq.mvp.view;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
public interface IFaceLoginView {
- void obtainFaceLoginData(FaceLoginResultBean resultBean);
+ void showProgress();
+
+ void hideProgress();
+
+ void obtainFaceLoginData(FaceResultBean resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
index c9783cd..fe666b1 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
@@ -3,6 +3,8 @@
import com.casic.birmm.hxrq.bean.LoginResultBean;
public interface ILoginView {
+ void showProgress();
+
void hideProgress();
void obtainLoginResult(LoginResultBean resultBean);
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
index 4e8821e..4003e26 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
@@ -3,5 +3,9 @@
import com.casic.birmm.hxrq.bean.QrCodeBean;
public interface IQrCodeDataView {
+ void showProgress();
+
+ void hideProgress();
+
void obtainQrCodeData(QrCodeBean userBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
new file mode 100644
index 0000000..4109e3c
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
@@ -0,0 +1,184 @@
+package com.casic.birmm.hxrq.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.ImageFormat;
+import android.hardware.Camera;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import androidx.annotation.NonNull;
+
+import com.casic.birmm.hxrq.R;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.utils.ImageHelper;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Stack;
+
+import butterknife.BindView;
+
+public class FacePreViewActivity extends BaseActivity implements Camera.PreviewCallback {
+
+ private static final int preViewWidth = 720;
+ private static final int preViewHeight = 1280;
+ @BindView(R.id.surfaceView)
+ SurfaceView surfaceView;
+ private SurfaceHolder mSurfaceHolder;
+ private Camera mCamera;
+ private ImageHelper imageHelper;
+ private Stack bitmapStack;
+ private boolean isCanLogin = true;
+
+ @Override
+ public int initLayoutView() {
+ return R.layout.activity_face;
+ }
+
+ @Override
+ protected void setupTopBarLayout() {
+
+ }
+
+ @Override
+ public void initData() {
+ imageHelper = new ImageHelper(this);
+ bitmapStack = new Stack<>();
+ }
+
+ @Override
+ public void initEvent() {
+ // 绑定SurfaceView,取得SurfaceHolder对象
+ mSurfaceHolder = surfaceView.getHolder();
+ mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(@NonNull SurfaceHolder holder) {
+ if (mCamera == null) {
+ //打开相机
+ openCamera();
+ }
+ try {
+ //预览画面
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ //开始预览
+ mCamera.startPreview();
+ }
+
+ @Override
+ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
+
+ }
+
+ @Override
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+ releaseCamera(); //释放相机资源
+ }
+ });
+ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置
+ }
+
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ camera.addCallbackBuffer(data);
+ Camera.Size size = camera.getParameters().getPreviewSize();//必须是相机支持的预览尺寸,否则颜色YUV空间会错位
+ Bitmap originBitmap = imageHelper.nv21ToBitmap(data, size.width, size.height);
+ //要使用Android内置的人脸识别,需要将Bitmap对象转为RGB_565格式,否则无法识别
+// Bitmap faceDetectorBitmap = originBitmap.copy(Bitmap.Config.RGB_565, true);
+// FaceDetector.Face[] faces = new FaceDetector.Face[1];
+// FaceDetector faceDetector = new FaceDetector(faceDetectorBitmap.getWidth(), faceDetectorBitmap.getHeight(), 1);
+// int faceSum = faceDetector.findFaces(faceDetectorBitmap, faces);
+// if (faceSum == 1) {
+ bitmapStack.push(originBitmap);
+ if (bitmapStack.size() >= 5) {//当栈里有5张bitmap之后才开始识别
+ if (isCanLogin) {
+ isCanLogin = false;
+ Bitmap bitmap = bitmapStack.pop();
+ Intent intent = new Intent();
+ intent.putExtra("imageToBase64", ImageHelper.imageToBase64(bitmap));
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ } else {
+ finish();
+ }
+ }
+// } else {
+// Log.d(TAG, "detectorFace: 未检测到人脸");
+// }
+ }
+
+ /**
+ * 打开相机
+ */
+ private void openCamera() {
+ try {
+ mCamera = Camera.open(1);
+ initParameters(mCamera); //初始化相机配置信息
+ mCamera.setPreviewCallback(this);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 初始化相机属性
+ */
+ private void initParameters(Camera camera) {
+ try {
+ Camera.Parameters mParameters = camera.getParameters();
+ mParameters.setPreviewFormat(ImageFormat.NV21); //设置预览图片的格式
+ //获取与指定宽高相等或最接近的尺寸
+ //设置预览尺寸
+ Camera.Size bestPreviewSize = obtainBestSize(preViewWidth, preViewHeight, mParameters.getSupportedPreviewSizes());
+ mParameters.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height);
+ //设置保存图片尺寸
+// Camera.Size bestPicSize = obtainBestSize(picWidth, picHeight, mParameters.getSupportedPictureSizes());
+// mParameters.setPictureSize(bestPicSize.width, bestPicSize.height);
+ //对焦模式
+ mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ camera.setDisplayOrientation(90);
+ camera.setParameters(mParameters);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 获取最合适的尺寸
+ */
+ private Camera.Size obtainBestSize(int targetWidth, int targetHeight, List sizeList) {
+ Camera.Size bestSize = null;
+ int targetRatio = targetHeight / targetWidth;//目标大小的宽高比
+ int minDiff = targetRatio;
+
+ for (Camera.Size size : sizeList) {
+ if (size.width == targetHeight && size.height == targetWidth) {
+ bestSize = size;
+ break;
+ }
+ int supportedRatio = (size.width / size.height);
+ if (Math.abs(supportedRatio - targetRatio) < minDiff) {
+ minDiff = Math.abs(supportedRatio - targetRatio);
+ bestSize = size;
+ }
+ }
+ return bestSize;
+ }
+
+ /**
+ * 释放相机资源
+ */
+ private void releaseCamera() {
+ if (mCamera != null) {
+ mCamera.stopPreview();
+ mCamera.setPreviewCallback(null);
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
index 98aef9d..30c26c8 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
@@ -8,14 +8,15 @@
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.casic.birmm.hxrq.R;
-import com.casic.birmm.hxrq.base.DoubleClickExitActivity;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -28,23 +29,16 @@
import com.casic.birmm.hxrq.mvp.view.IFaceLoginView;
import com.casic.birmm.hxrq.mvp.view.ILoginView;
import com.casic.birmm.hxrq.mvp.view.IQrCodeDataView;
-import com.casic.birmm.hxrq.utils.FileUtils;
-import com.casic.birmm.hxrq.utils.GlideLoadEngine;
+import com.casic.birmm.hxrq.utils.Constant;
import com.casic.birmm.hxrq.utils.RSAUtils;
import com.casic.birmm.hxrq.utils.SaveKeyValues;
-import com.casic.birmm.hxrq.utils.StringHelper;
import com.casic.birmm.hxrq.utils.TokenHelper;
import com.google.gson.Gson;
-import com.luck.picture.lib.PictureSelector;
-import com.luck.picture.lib.config.PictureConfig;
-import com.luck.picture.lib.config.PictureMimeType;
-import com.luck.picture.lib.entity.LocalMedia;
import com.qmuiteam.qmui.util.QMUIStatusBarHelper;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton;
-import java.io.File;
import java.security.PublicKey;
import butterknife.BindView;
@@ -53,15 +47,11 @@
import cn.bertsir.zbar.QrConfig;
import cn.bertsir.zbar.QrManager;
import cn.bertsir.zbar.view.ScanLineView;
-import top.zibin.luban.CompressionPredicate;
-import top.zibin.luban.Luban;
-import top.zibin.luban.OnCompressListener;
-public class LoginActivity extends DoubleClickExitActivity
- implements View.OnClickListener, IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
+public class LoginActivity extends BaseActivity implements View.OnClickListener,
+ IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
private static final String TAG = "LoginActivity";
-
@BindView(R.id.userNameView)
EditText userNameView;
@BindView(R.id.userPasswordView)
@@ -76,8 +66,8 @@
private LoginPresenterImpl loginPresenter;
private QrCodePresenterImpl qrCodePresenter;
private FaceLoginPresenterImpl faceLoginPresenter;
- private String userName;
- private String userPassword;
+ private boolean isPasswordLogin = false;
+ private String qrCode = "";
@Override
public int initLayoutView() {
@@ -86,20 +76,29 @@
@Override
protected void setupTopBarLayout() {
- //TODO 此页面无需实现
+ //设置状态栏黑色字体图标
+ QMUIStatusBarHelper.setStatusBarLightMode(this);
}
@Override
public void initData() {
- //设置状态栏黑色字体图标
- QMUIStatusBarHelper.setStatusBarLightMode(this);
-
String userName = (String) SaveKeyValues.getValue("userName", "");
String userPassword = (String) SaveKeyValues.getValue("userPassword", "");
+ userNameView.setText(userName);
+ userPasswordView.setText(userPassword);
if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) {
- userNameView.setText(userName);
- userPasswordView.setText(userPassword);
+ rememberPasswordView.setChecked(true);
+ } else {
+ rememberPasswordView.setChecked(false);
}
+ rememberPasswordView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (!isChecked) {
+ SaveKeyValues.removeKey("userPassword");
+ }
+ }
+ });
loadingDialog = new QMUITipDialog.Builder(this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
.setTipWord("登陆中,请稍后")
@@ -124,14 +123,9 @@
public void onClick(View v) {
switch (v.getId()) {
case R.id.loginButton:
- userName = userNameView.getText().toString();
- userPassword = userPasswordView.getText().toString();
- if (rememberPasswordView.isChecked()) {
- SaveKeyValues.putValue("userName", userName);
- SaveKeyValues.putValue("userPassword", userPassword);
- }
//密码登录前需要验证sid
authenticatePresenter.onReadyRetrofitRequest();
+ isPasswordLogin = true;
break;
case R.id.changeLoginModeView:
//首次登录不可用扫码,因为还未注册
@@ -169,50 +163,19 @@
}
private void captureFaceData() {
- //TODO 调相机,捕获人脸数据,并保存为文件得到路径
- PictureSelector.create(this)
- .openCamera(PictureMimeType.ofImage())
- .imageEngine(GlideLoadEngine.createGlideEngine())
- .maxSelectNum(1)
- .forResult(PictureConfig.REQUEST_CAMERA);
+ // 调相机,捕获人脸数据,并保存为文件得到路径
+ startActivityForResult(new Intent(this, FacePreViewActivity.class), Constant.FACE_DETECTOR_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
- if (requestCode == PictureConfig.REQUEST_CAMERA) {
- LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0);
- Luban.with(this)
- .load(localMedia.getRealPath())
- .ignoreBy(100)
- .setTargetDir(FileUtils.getFileDir("CompressImageFile"))
- .filter(new CompressionPredicate() {
- @Override
- public boolean apply(String path) {
- return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));
- }
- })
- .setCompressListener(new OnCompressListener() {
- @Override
- public void onStart() {
- // TODO 压缩开始前调用,可以在方法内启动 loading UI
- }
-
- @Override
- public void onSuccess(File file) {
- String imageToBase64 = StringHelper.imageToBase64(file);
-
- ImageBean imageBean = new ImageBean();
- imageBean.setImage(imageToBase64);
- faceLoginPresenter.onReadyRetrofitRequest(imageBean);
- }
-
- @Override
- public void onError(Throwable e) {
- // TODO 当压缩过程出现问题时调用
- }
- }).launch();
+ if (requestCode == Constant.FACE_DETECTOR_CODE) {
+ String imageToBase64 = data.getStringExtra("imageToBase64");
+ ImageBean imageBean = new ImageBean();
+ imageBean.setImage(imageToBase64);
+ faceLoginPresenter.onReadyRetrofitRequest(imageBean);
}
}
}
@@ -232,7 +195,7 @@
.setPlaySound(true)//是否扫描成功后bi~的声音
.setDingPath(R.raw.qrcode)//设置提示音(不设置为默认的Ding~)
.setIsOnlyCenter(true)//是否只识别框中内容(默认为全屏识别)
- .setTitleBackgroudColor(Color.parseColor("#262020"))//设置状态栏颜色
+ .setTitleBackgroudColor(R.color.black)//设置状态栏颜色
.setTitleTextColor(Color.WHITE)//设置Title文字颜色
.setScreenOrientation(QrConfig.SCREEN_PORTRAIT)//设置屏幕方式
.setScanLineStyle(ScanLineView.style_hybrid)//扫描线样式
@@ -241,8 +204,8 @@
QrManager.getInstance().init(qrConfig).startScan(this, new QrManager.OnScanResultCallback() {
@Override
public void onScanSuccess(final ScanResult result) {
-// Log.d(TAG, "扫码结果: " + result.content);
- qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), result.content);
+ qrCode = result.content;
+ authenticatePresenter.onReadyRetrofitRequest();//需要时时保持最新token,所以扫码登录之前需要获取最新token
}
});
}
@@ -254,9 +217,15 @@
@Override
public void authenticateResult(PublicKeyBean result) {
- Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
+// Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
if (result.isSuccess()) {
PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey());
+ String userName = userNameView.getText().toString();
+ String userPassword = userPasswordView.getText().toString();
+ if (rememberPasswordView.isChecked()) {
+ SaveKeyValues.putValue("userName", userName);
+ SaveKeyValues.putValue("userPassword", userPassword);
+ }
if (TextUtils.isEmpty(userName)) {
Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show();
return;
@@ -266,7 +235,6 @@
return;
}
String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey);
- Log.d(TAG, "authenticateResult: 验证成功,开始登录");
//登录并获取Token,POST请求
loginPresenter.onReadyRetrofitRequest(result.getData().getSid(), userName, dataByPublicKey);
} else {
@@ -283,11 +251,14 @@
String token = result.getData().getToken();
if (!TextUtils.isEmpty(token)) {
//获取用户信息
- Log.d(TAG, "obtainLoginResult: 获取Token成功");
TokenHelper.saveToken(token);
//验证成功登录
- startActivity(new Intent(this, MainActivity.class));
- finish();
+ if (isPasswordLogin) {
+ startActivity(new Intent(this, MainActivity.class));
+ finish();
+ } else {
+ qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), qrCode);
+ }
}
}
@@ -307,15 +278,17 @@
}
@Override
- public void obtainFaceLoginData(FaceLoginResultBean resultBean) {
-// Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
- if (resultBean.getCode() == 200) {
+ public void obtainFaceLoginData(FaceResultBean resultBean) {
+ Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
+ if (resultBean.isSuccess()) {
+ //{"code":200,"data":{"kaptcha":"","token":"9135bcb7-4f39-4b7a-a10e-555406ddb9e1"},"exceptionClazz":"","message":"登录成功","success":true}
TokenHelper.saveToken(resultBean.getData().getToken());
//验证成功登录
startActivity(new Intent(this, MainActivity.class));
finish();
} else {
- Toast.makeText(this, "无法解析人脸", Toast.LENGTH_SHORT).show();
+ //{"code":200,"data":"","exceptionClazz":"","message":"图片中没有人脸","success":false}
+ Toast.makeText(this, "人脸识别失败", Toast.LENGTH_SHORT).show();
}
}
@@ -336,5 +309,8 @@
if (qrCodePresenter != null) {
qrCodePresenter.disposeRetrofitRequest();
}
+ if (faceLoginPresenter != null) {
+ faceLoginPresenter.disposeRetrofitRequest();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
index e8e9b75..759a94d 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
@@ -9,4 +9,5 @@
Manifest.permission.WRITE_EXTERNAL_STORAGE};
public static final int PERMISSIONS_CODE = 999;
+ public static final int FACE_DETECTOR_CODE = 998;
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
new file mode 100644
index 0000000..b774ee9
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
@@ -0,0 +1,95 @@
+package com.casic.birmm.hxrq.utils;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.ImageFormat;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.YuvImage;
+import android.util.Base64;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class ImageHelper {
+
+ public ImageHelper(Context context) {
+
+ }
+
+ public Bitmap nv21ToBitmap(byte[] nv21, int width, int height) {
+ Bitmap bitmap = null;
+ try {
+ final YuvImage image = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ image.compressToJpeg(new Rect(0, 0, width, height), 80, outputStream);
+ final Bitmap bmp = BitmapFactory.decodeByteArray(outputStream.toByteArray(), 0, outputStream.size());
+ bitmap = rotateImageView(-90, bmp);
+ outputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return bitmap;
+ }
+
+ public Bitmap rotateImageView(int angle, Bitmap bitmap) {
+ //旋转图片 动作
+ Matrix matrix = new Matrix();
+ matrix.postRotate(angle);
+ // 创建新的图片
+ return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(File file) {
+ if (file == null) {
+ return null;
+ }
+ try {
+ FileInputStream fis = new FileInputStream(file);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] b = new byte[1024];
+ int n;
+ while ((n = fis.read(b)) != -1) {
+ bos.write(b, 0, n);
+ }
+ fis.close();
+ bos.close();
+
+ byte[] imgBytes = bos.toByteArray();
+ String result = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(Bitmap bitmap) {
+ if (bitmap == null) {
+ return null;
+ }
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);//压缩质量
+
+ outputStream.flush();
+ outputStream.close();
+
+ byte[] bitmapBytes = outputStream.toByteArray();
+ String result = Base64.encodeToString(bitmapBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (IOException e) {
+ return null;
+ }
+ }
+}
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
index c6d3e33..7e502f2 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
@@ -1,7 +1,11 @@
package com.casic.birmm.hxrq.mvp.view;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
public interface IFaceLoginView {
- void obtainFaceLoginData(FaceLoginResultBean resultBean);
+ void showProgress();
+
+ void hideProgress();
+
+ void obtainFaceLoginData(FaceResultBean resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
index c9783cd..fe666b1 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
@@ -3,6 +3,8 @@
import com.casic.birmm.hxrq.bean.LoginResultBean;
public interface ILoginView {
+ void showProgress();
+
void hideProgress();
void obtainLoginResult(LoginResultBean resultBean);
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
index 4e8821e..4003e26 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
@@ -3,5 +3,9 @@
import com.casic.birmm.hxrq.bean.QrCodeBean;
public interface IQrCodeDataView {
+ void showProgress();
+
+ void hideProgress();
+
void obtainQrCodeData(QrCodeBean userBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
new file mode 100644
index 0000000..4109e3c
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
@@ -0,0 +1,184 @@
+package com.casic.birmm.hxrq.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.ImageFormat;
+import android.hardware.Camera;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import androidx.annotation.NonNull;
+
+import com.casic.birmm.hxrq.R;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.utils.ImageHelper;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Stack;
+
+import butterknife.BindView;
+
+public class FacePreViewActivity extends BaseActivity implements Camera.PreviewCallback {
+
+ private static final int preViewWidth = 720;
+ private static final int preViewHeight = 1280;
+ @BindView(R.id.surfaceView)
+ SurfaceView surfaceView;
+ private SurfaceHolder mSurfaceHolder;
+ private Camera mCamera;
+ private ImageHelper imageHelper;
+ private Stack bitmapStack;
+ private boolean isCanLogin = true;
+
+ @Override
+ public int initLayoutView() {
+ return R.layout.activity_face;
+ }
+
+ @Override
+ protected void setupTopBarLayout() {
+
+ }
+
+ @Override
+ public void initData() {
+ imageHelper = new ImageHelper(this);
+ bitmapStack = new Stack<>();
+ }
+
+ @Override
+ public void initEvent() {
+ // 绑定SurfaceView,取得SurfaceHolder对象
+ mSurfaceHolder = surfaceView.getHolder();
+ mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(@NonNull SurfaceHolder holder) {
+ if (mCamera == null) {
+ //打开相机
+ openCamera();
+ }
+ try {
+ //预览画面
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ //开始预览
+ mCamera.startPreview();
+ }
+
+ @Override
+ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
+
+ }
+
+ @Override
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+ releaseCamera(); //释放相机资源
+ }
+ });
+ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置
+ }
+
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ camera.addCallbackBuffer(data);
+ Camera.Size size = camera.getParameters().getPreviewSize();//必须是相机支持的预览尺寸,否则颜色YUV空间会错位
+ Bitmap originBitmap = imageHelper.nv21ToBitmap(data, size.width, size.height);
+ //要使用Android内置的人脸识别,需要将Bitmap对象转为RGB_565格式,否则无法识别
+// Bitmap faceDetectorBitmap = originBitmap.copy(Bitmap.Config.RGB_565, true);
+// FaceDetector.Face[] faces = new FaceDetector.Face[1];
+// FaceDetector faceDetector = new FaceDetector(faceDetectorBitmap.getWidth(), faceDetectorBitmap.getHeight(), 1);
+// int faceSum = faceDetector.findFaces(faceDetectorBitmap, faces);
+// if (faceSum == 1) {
+ bitmapStack.push(originBitmap);
+ if (bitmapStack.size() >= 5) {//当栈里有5张bitmap之后才开始识别
+ if (isCanLogin) {
+ isCanLogin = false;
+ Bitmap bitmap = bitmapStack.pop();
+ Intent intent = new Intent();
+ intent.putExtra("imageToBase64", ImageHelper.imageToBase64(bitmap));
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ } else {
+ finish();
+ }
+ }
+// } else {
+// Log.d(TAG, "detectorFace: 未检测到人脸");
+// }
+ }
+
+ /**
+ * 打开相机
+ */
+ private void openCamera() {
+ try {
+ mCamera = Camera.open(1);
+ initParameters(mCamera); //初始化相机配置信息
+ mCamera.setPreviewCallback(this);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 初始化相机属性
+ */
+ private void initParameters(Camera camera) {
+ try {
+ Camera.Parameters mParameters = camera.getParameters();
+ mParameters.setPreviewFormat(ImageFormat.NV21); //设置预览图片的格式
+ //获取与指定宽高相等或最接近的尺寸
+ //设置预览尺寸
+ Camera.Size bestPreviewSize = obtainBestSize(preViewWidth, preViewHeight, mParameters.getSupportedPreviewSizes());
+ mParameters.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height);
+ //设置保存图片尺寸
+// Camera.Size bestPicSize = obtainBestSize(picWidth, picHeight, mParameters.getSupportedPictureSizes());
+// mParameters.setPictureSize(bestPicSize.width, bestPicSize.height);
+ //对焦模式
+ mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ camera.setDisplayOrientation(90);
+ camera.setParameters(mParameters);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 获取最合适的尺寸
+ */
+ private Camera.Size obtainBestSize(int targetWidth, int targetHeight, List sizeList) {
+ Camera.Size bestSize = null;
+ int targetRatio = targetHeight / targetWidth;//目标大小的宽高比
+ int minDiff = targetRatio;
+
+ for (Camera.Size size : sizeList) {
+ if (size.width == targetHeight && size.height == targetWidth) {
+ bestSize = size;
+ break;
+ }
+ int supportedRatio = (size.width / size.height);
+ if (Math.abs(supportedRatio - targetRatio) < minDiff) {
+ minDiff = Math.abs(supportedRatio - targetRatio);
+ bestSize = size;
+ }
+ }
+ return bestSize;
+ }
+
+ /**
+ * 释放相机资源
+ */
+ private void releaseCamera() {
+ if (mCamera != null) {
+ mCamera.stopPreview();
+ mCamera.setPreviewCallback(null);
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
index 98aef9d..30c26c8 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
@@ -8,14 +8,15 @@
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.casic.birmm.hxrq.R;
-import com.casic.birmm.hxrq.base.DoubleClickExitActivity;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -28,23 +29,16 @@
import com.casic.birmm.hxrq.mvp.view.IFaceLoginView;
import com.casic.birmm.hxrq.mvp.view.ILoginView;
import com.casic.birmm.hxrq.mvp.view.IQrCodeDataView;
-import com.casic.birmm.hxrq.utils.FileUtils;
-import com.casic.birmm.hxrq.utils.GlideLoadEngine;
+import com.casic.birmm.hxrq.utils.Constant;
import com.casic.birmm.hxrq.utils.RSAUtils;
import com.casic.birmm.hxrq.utils.SaveKeyValues;
-import com.casic.birmm.hxrq.utils.StringHelper;
import com.casic.birmm.hxrq.utils.TokenHelper;
import com.google.gson.Gson;
-import com.luck.picture.lib.PictureSelector;
-import com.luck.picture.lib.config.PictureConfig;
-import com.luck.picture.lib.config.PictureMimeType;
-import com.luck.picture.lib.entity.LocalMedia;
import com.qmuiteam.qmui.util.QMUIStatusBarHelper;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton;
-import java.io.File;
import java.security.PublicKey;
import butterknife.BindView;
@@ -53,15 +47,11 @@
import cn.bertsir.zbar.QrConfig;
import cn.bertsir.zbar.QrManager;
import cn.bertsir.zbar.view.ScanLineView;
-import top.zibin.luban.CompressionPredicate;
-import top.zibin.luban.Luban;
-import top.zibin.luban.OnCompressListener;
-public class LoginActivity extends DoubleClickExitActivity
- implements View.OnClickListener, IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
+public class LoginActivity extends BaseActivity implements View.OnClickListener,
+ IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
private static final String TAG = "LoginActivity";
-
@BindView(R.id.userNameView)
EditText userNameView;
@BindView(R.id.userPasswordView)
@@ -76,8 +66,8 @@
private LoginPresenterImpl loginPresenter;
private QrCodePresenterImpl qrCodePresenter;
private FaceLoginPresenterImpl faceLoginPresenter;
- private String userName;
- private String userPassword;
+ private boolean isPasswordLogin = false;
+ private String qrCode = "";
@Override
public int initLayoutView() {
@@ -86,20 +76,29 @@
@Override
protected void setupTopBarLayout() {
- //TODO 此页面无需实现
+ //设置状态栏黑色字体图标
+ QMUIStatusBarHelper.setStatusBarLightMode(this);
}
@Override
public void initData() {
- //设置状态栏黑色字体图标
- QMUIStatusBarHelper.setStatusBarLightMode(this);
-
String userName = (String) SaveKeyValues.getValue("userName", "");
String userPassword = (String) SaveKeyValues.getValue("userPassword", "");
+ userNameView.setText(userName);
+ userPasswordView.setText(userPassword);
if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) {
- userNameView.setText(userName);
- userPasswordView.setText(userPassword);
+ rememberPasswordView.setChecked(true);
+ } else {
+ rememberPasswordView.setChecked(false);
}
+ rememberPasswordView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (!isChecked) {
+ SaveKeyValues.removeKey("userPassword");
+ }
+ }
+ });
loadingDialog = new QMUITipDialog.Builder(this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
.setTipWord("登陆中,请稍后")
@@ -124,14 +123,9 @@
public void onClick(View v) {
switch (v.getId()) {
case R.id.loginButton:
- userName = userNameView.getText().toString();
- userPassword = userPasswordView.getText().toString();
- if (rememberPasswordView.isChecked()) {
- SaveKeyValues.putValue("userName", userName);
- SaveKeyValues.putValue("userPassword", userPassword);
- }
//密码登录前需要验证sid
authenticatePresenter.onReadyRetrofitRequest();
+ isPasswordLogin = true;
break;
case R.id.changeLoginModeView:
//首次登录不可用扫码,因为还未注册
@@ -169,50 +163,19 @@
}
private void captureFaceData() {
- //TODO 调相机,捕获人脸数据,并保存为文件得到路径
- PictureSelector.create(this)
- .openCamera(PictureMimeType.ofImage())
- .imageEngine(GlideLoadEngine.createGlideEngine())
- .maxSelectNum(1)
- .forResult(PictureConfig.REQUEST_CAMERA);
+ // 调相机,捕获人脸数据,并保存为文件得到路径
+ startActivityForResult(new Intent(this, FacePreViewActivity.class), Constant.FACE_DETECTOR_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
- if (requestCode == PictureConfig.REQUEST_CAMERA) {
- LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0);
- Luban.with(this)
- .load(localMedia.getRealPath())
- .ignoreBy(100)
- .setTargetDir(FileUtils.getFileDir("CompressImageFile"))
- .filter(new CompressionPredicate() {
- @Override
- public boolean apply(String path) {
- return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));
- }
- })
- .setCompressListener(new OnCompressListener() {
- @Override
- public void onStart() {
- // TODO 压缩开始前调用,可以在方法内启动 loading UI
- }
-
- @Override
- public void onSuccess(File file) {
- String imageToBase64 = StringHelper.imageToBase64(file);
-
- ImageBean imageBean = new ImageBean();
- imageBean.setImage(imageToBase64);
- faceLoginPresenter.onReadyRetrofitRequest(imageBean);
- }
-
- @Override
- public void onError(Throwable e) {
- // TODO 当压缩过程出现问题时调用
- }
- }).launch();
+ if (requestCode == Constant.FACE_DETECTOR_CODE) {
+ String imageToBase64 = data.getStringExtra("imageToBase64");
+ ImageBean imageBean = new ImageBean();
+ imageBean.setImage(imageToBase64);
+ faceLoginPresenter.onReadyRetrofitRequest(imageBean);
}
}
}
@@ -232,7 +195,7 @@
.setPlaySound(true)//是否扫描成功后bi~的声音
.setDingPath(R.raw.qrcode)//设置提示音(不设置为默认的Ding~)
.setIsOnlyCenter(true)//是否只识别框中内容(默认为全屏识别)
- .setTitleBackgroudColor(Color.parseColor("#262020"))//设置状态栏颜色
+ .setTitleBackgroudColor(R.color.black)//设置状态栏颜色
.setTitleTextColor(Color.WHITE)//设置Title文字颜色
.setScreenOrientation(QrConfig.SCREEN_PORTRAIT)//设置屏幕方式
.setScanLineStyle(ScanLineView.style_hybrid)//扫描线样式
@@ -241,8 +204,8 @@
QrManager.getInstance().init(qrConfig).startScan(this, new QrManager.OnScanResultCallback() {
@Override
public void onScanSuccess(final ScanResult result) {
-// Log.d(TAG, "扫码结果: " + result.content);
- qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), result.content);
+ qrCode = result.content;
+ authenticatePresenter.onReadyRetrofitRequest();//需要时时保持最新token,所以扫码登录之前需要获取最新token
}
});
}
@@ -254,9 +217,15 @@
@Override
public void authenticateResult(PublicKeyBean result) {
- Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
+// Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
if (result.isSuccess()) {
PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey());
+ String userName = userNameView.getText().toString();
+ String userPassword = userPasswordView.getText().toString();
+ if (rememberPasswordView.isChecked()) {
+ SaveKeyValues.putValue("userName", userName);
+ SaveKeyValues.putValue("userPassword", userPassword);
+ }
if (TextUtils.isEmpty(userName)) {
Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show();
return;
@@ -266,7 +235,6 @@
return;
}
String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey);
- Log.d(TAG, "authenticateResult: 验证成功,开始登录");
//登录并获取Token,POST请求
loginPresenter.onReadyRetrofitRequest(result.getData().getSid(), userName, dataByPublicKey);
} else {
@@ -283,11 +251,14 @@
String token = result.getData().getToken();
if (!TextUtils.isEmpty(token)) {
//获取用户信息
- Log.d(TAG, "obtainLoginResult: 获取Token成功");
TokenHelper.saveToken(token);
//验证成功登录
- startActivity(new Intent(this, MainActivity.class));
- finish();
+ if (isPasswordLogin) {
+ startActivity(new Intent(this, MainActivity.class));
+ finish();
+ } else {
+ qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), qrCode);
+ }
}
}
@@ -307,15 +278,17 @@
}
@Override
- public void obtainFaceLoginData(FaceLoginResultBean resultBean) {
-// Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
- if (resultBean.getCode() == 200) {
+ public void obtainFaceLoginData(FaceResultBean resultBean) {
+ Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
+ if (resultBean.isSuccess()) {
+ //{"code":200,"data":{"kaptcha":"","token":"9135bcb7-4f39-4b7a-a10e-555406ddb9e1"},"exceptionClazz":"","message":"登录成功","success":true}
TokenHelper.saveToken(resultBean.getData().getToken());
//验证成功登录
startActivity(new Intent(this, MainActivity.class));
finish();
} else {
- Toast.makeText(this, "无法解析人脸", Toast.LENGTH_SHORT).show();
+ //{"code":200,"data":"","exceptionClazz":"","message":"图片中没有人脸","success":false}
+ Toast.makeText(this, "人脸识别失败", Toast.LENGTH_SHORT).show();
}
}
@@ -336,5 +309,8 @@
if (qrCodePresenter != null) {
qrCodePresenter.disposeRetrofitRequest();
}
+ if (faceLoginPresenter != null) {
+ faceLoginPresenter.disposeRetrofitRequest();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
index e8e9b75..759a94d 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
@@ -9,4 +9,5 @@
Manifest.permission.WRITE_EXTERNAL_STORAGE};
public static final int PERMISSIONS_CODE = 999;
+ public static final int FACE_DETECTOR_CODE = 998;
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
new file mode 100644
index 0000000..b774ee9
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
@@ -0,0 +1,95 @@
+package com.casic.birmm.hxrq.utils;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.ImageFormat;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.YuvImage;
+import android.util.Base64;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class ImageHelper {
+
+ public ImageHelper(Context context) {
+
+ }
+
+ public Bitmap nv21ToBitmap(byte[] nv21, int width, int height) {
+ Bitmap bitmap = null;
+ try {
+ final YuvImage image = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ image.compressToJpeg(new Rect(0, 0, width, height), 80, outputStream);
+ final Bitmap bmp = BitmapFactory.decodeByteArray(outputStream.toByteArray(), 0, outputStream.size());
+ bitmap = rotateImageView(-90, bmp);
+ outputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return bitmap;
+ }
+
+ public Bitmap rotateImageView(int angle, Bitmap bitmap) {
+ //旋转图片 动作
+ Matrix matrix = new Matrix();
+ matrix.postRotate(angle);
+ // 创建新的图片
+ return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(File file) {
+ if (file == null) {
+ return null;
+ }
+ try {
+ FileInputStream fis = new FileInputStream(file);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] b = new byte[1024];
+ int n;
+ while ((n = fis.read(b)) != -1) {
+ bos.write(b, 0, n);
+ }
+ fis.close();
+ bos.close();
+
+ byte[] imgBytes = bos.toByteArray();
+ String result = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(Bitmap bitmap) {
+ if (bitmap == null) {
+ return null;
+ }
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);//压缩质量
+
+ outputStream.flush();
+ outputStream.close();
+
+ byte[] bitmapBytes = outputStream.toByteArray();
+ String result = Base64.encodeToString(bitmapBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (IOException e) {
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
index f4af6a5..e7772dd 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
@@ -3,33 +3,26 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
-import android.util.Log;
public class SaveKeyValues {
- private static final String TAG = "SaveKeyValues";
-
- @SuppressLint({"StaticFieldLeak"})
- private static Context context;
private static SharedPreferences sharedPreferences;
private static SharedPreferences.Editor editor;
- private static String fileName;
+ @SuppressLint("CommitPrefEdits")
public static void initSharedPreferences(Context mContext) {
- context = mContext.getApplicationContext();
- String packageName = context.getPackageName();
+ String packageName = mContext.getPackageName();
//获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms
String[] split = packageName.split("\\.");//先转义.之后才能分割
int length = split.length;
- fileName = split[length - 1];
- Log.d(TAG, fileName);
+ String fileName = split[length - 1];
+ sharedPreferences = mContext.getSharedPreferences(fileName, Context.MODE_PRIVATE);
+ editor = sharedPreferences.edit();
}
/**
* 存储
*/
public static void putValue(String key, Object object) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
- editor = sharedPreferences.edit();
if (object instanceof String) {
editor.putString(key, (String) object);
} else if (object instanceof Integer) {
@@ -50,7 +43,6 @@
* 获取保存的数据
*/
public static Object getValue(String key, Object defaultObject) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
if (defaultObject instanceof String) {
return sharedPreferences.getString(key, (String) defaultObject);
} else if (defaultObject instanceof Integer) {
@@ -86,7 +78,6 @@
* 查询某个key是否存在
*/
public static boolean containsKey(String key) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
return sharedPreferences.contains(key);
}
}
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
index c6d3e33..7e502f2 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
@@ -1,7 +1,11 @@
package com.casic.birmm.hxrq.mvp.view;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
public interface IFaceLoginView {
- void obtainFaceLoginData(FaceLoginResultBean resultBean);
+ void showProgress();
+
+ void hideProgress();
+
+ void obtainFaceLoginData(FaceResultBean resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
index c9783cd..fe666b1 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
@@ -3,6 +3,8 @@
import com.casic.birmm.hxrq.bean.LoginResultBean;
public interface ILoginView {
+ void showProgress();
+
void hideProgress();
void obtainLoginResult(LoginResultBean resultBean);
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
index 4e8821e..4003e26 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
@@ -3,5 +3,9 @@
import com.casic.birmm.hxrq.bean.QrCodeBean;
public interface IQrCodeDataView {
+ void showProgress();
+
+ void hideProgress();
+
void obtainQrCodeData(QrCodeBean userBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
new file mode 100644
index 0000000..4109e3c
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
@@ -0,0 +1,184 @@
+package com.casic.birmm.hxrq.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.ImageFormat;
+import android.hardware.Camera;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import androidx.annotation.NonNull;
+
+import com.casic.birmm.hxrq.R;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.utils.ImageHelper;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Stack;
+
+import butterknife.BindView;
+
+public class FacePreViewActivity extends BaseActivity implements Camera.PreviewCallback {
+
+ private static final int preViewWidth = 720;
+ private static final int preViewHeight = 1280;
+ @BindView(R.id.surfaceView)
+ SurfaceView surfaceView;
+ private SurfaceHolder mSurfaceHolder;
+ private Camera mCamera;
+ private ImageHelper imageHelper;
+ private Stack bitmapStack;
+ private boolean isCanLogin = true;
+
+ @Override
+ public int initLayoutView() {
+ return R.layout.activity_face;
+ }
+
+ @Override
+ protected void setupTopBarLayout() {
+
+ }
+
+ @Override
+ public void initData() {
+ imageHelper = new ImageHelper(this);
+ bitmapStack = new Stack<>();
+ }
+
+ @Override
+ public void initEvent() {
+ // 绑定SurfaceView,取得SurfaceHolder对象
+ mSurfaceHolder = surfaceView.getHolder();
+ mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(@NonNull SurfaceHolder holder) {
+ if (mCamera == null) {
+ //打开相机
+ openCamera();
+ }
+ try {
+ //预览画面
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ //开始预览
+ mCamera.startPreview();
+ }
+
+ @Override
+ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
+
+ }
+
+ @Override
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+ releaseCamera(); //释放相机资源
+ }
+ });
+ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置
+ }
+
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ camera.addCallbackBuffer(data);
+ Camera.Size size = camera.getParameters().getPreviewSize();//必须是相机支持的预览尺寸,否则颜色YUV空间会错位
+ Bitmap originBitmap = imageHelper.nv21ToBitmap(data, size.width, size.height);
+ //要使用Android内置的人脸识别,需要将Bitmap对象转为RGB_565格式,否则无法识别
+// Bitmap faceDetectorBitmap = originBitmap.copy(Bitmap.Config.RGB_565, true);
+// FaceDetector.Face[] faces = new FaceDetector.Face[1];
+// FaceDetector faceDetector = new FaceDetector(faceDetectorBitmap.getWidth(), faceDetectorBitmap.getHeight(), 1);
+// int faceSum = faceDetector.findFaces(faceDetectorBitmap, faces);
+// if (faceSum == 1) {
+ bitmapStack.push(originBitmap);
+ if (bitmapStack.size() >= 5) {//当栈里有5张bitmap之后才开始识别
+ if (isCanLogin) {
+ isCanLogin = false;
+ Bitmap bitmap = bitmapStack.pop();
+ Intent intent = new Intent();
+ intent.putExtra("imageToBase64", ImageHelper.imageToBase64(bitmap));
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ } else {
+ finish();
+ }
+ }
+// } else {
+// Log.d(TAG, "detectorFace: 未检测到人脸");
+// }
+ }
+
+ /**
+ * 打开相机
+ */
+ private void openCamera() {
+ try {
+ mCamera = Camera.open(1);
+ initParameters(mCamera); //初始化相机配置信息
+ mCamera.setPreviewCallback(this);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 初始化相机属性
+ */
+ private void initParameters(Camera camera) {
+ try {
+ Camera.Parameters mParameters = camera.getParameters();
+ mParameters.setPreviewFormat(ImageFormat.NV21); //设置预览图片的格式
+ //获取与指定宽高相等或最接近的尺寸
+ //设置预览尺寸
+ Camera.Size bestPreviewSize = obtainBestSize(preViewWidth, preViewHeight, mParameters.getSupportedPreviewSizes());
+ mParameters.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height);
+ //设置保存图片尺寸
+// Camera.Size bestPicSize = obtainBestSize(picWidth, picHeight, mParameters.getSupportedPictureSizes());
+// mParameters.setPictureSize(bestPicSize.width, bestPicSize.height);
+ //对焦模式
+ mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ camera.setDisplayOrientation(90);
+ camera.setParameters(mParameters);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 获取最合适的尺寸
+ */
+ private Camera.Size obtainBestSize(int targetWidth, int targetHeight, List sizeList) {
+ Camera.Size bestSize = null;
+ int targetRatio = targetHeight / targetWidth;//目标大小的宽高比
+ int minDiff = targetRatio;
+
+ for (Camera.Size size : sizeList) {
+ if (size.width == targetHeight && size.height == targetWidth) {
+ bestSize = size;
+ break;
+ }
+ int supportedRatio = (size.width / size.height);
+ if (Math.abs(supportedRatio - targetRatio) < minDiff) {
+ minDiff = Math.abs(supportedRatio - targetRatio);
+ bestSize = size;
+ }
+ }
+ return bestSize;
+ }
+
+ /**
+ * 释放相机资源
+ */
+ private void releaseCamera() {
+ if (mCamera != null) {
+ mCamera.stopPreview();
+ mCamera.setPreviewCallback(null);
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
index 98aef9d..30c26c8 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
@@ -8,14 +8,15 @@
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.casic.birmm.hxrq.R;
-import com.casic.birmm.hxrq.base.DoubleClickExitActivity;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -28,23 +29,16 @@
import com.casic.birmm.hxrq.mvp.view.IFaceLoginView;
import com.casic.birmm.hxrq.mvp.view.ILoginView;
import com.casic.birmm.hxrq.mvp.view.IQrCodeDataView;
-import com.casic.birmm.hxrq.utils.FileUtils;
-import com.casic.birmm.hxrq.utils.GlideLoadEngine;
+import com.casic.birmm.hxrq.utils.Constant;
import com.casic.birmm.hxrq.utils.RSAUtils;
import com.casic.birmm.hxrq.utils.SaveKeyValues;
-import com.casic.birmm.hxrq.utils.StringHelper;
import com.casic.birmm.hxrq.utils.TokenHelper;
import com.google.gson.Gson;
-import com.luck.picture.lib.PictureSelector;
-import com.luck.picture.lib.config.PictureConfig;
-import com.luck.picture.lib.config.PictureMimeType;
-import com.luck.picture.lib.entity.LocalMedia;
import com.qmuiteam.qmui.util.QMUIStatusBarHelper;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton;
-import java.io.File;
import java.security.PublicKey;
import butterknife.BindView;
@@ -53,15 +47,11 @@
import cn.bertsir.zbar.QrConfig;
import cn.bertsir.zbar.QrManager;
import cn.bertsir.zbar.view.ScanLineView;
-import top.zibin.luban.CompressionPredicate;
-import top.zibin.luban.Luban;
-import top.zibin.luban.OnCompressListener;
-public class LoginActivity extends DoubleClickExitActivity
- implements View.OnClickListener, IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
+public class LoginActivity extends BaseActivity implements View.OnClickListener,
+ IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
private static final String TAG = "LoginActivity";
-
@BindView(R.id.userNameView)
EditText userNameView;
@BindView(R.id.userPasswordView)
@@ -76,8 +66,8 @@
private LoginPresenterImpl loginPresenter;
private QrCodePresenterImpl qrCodePresenter;
private FaceLoginPresenterImpl faceLoginPresenter;
- private String userName;
- private String userPassword;
+ private boolean isPasswordLogin = false;
+ private String qrCode = "";
@Override
public int initLayoutView() {
@@ -86,20 +76,29 @@
@Override
protected void setupTopBarLayout() {
- //TODO 此页面无需实现
+ //设置状态栏黑色字体图标
+ QMUIStatusBarHelper.setStatusBarLightMode(this);
}
@Override
public void initData() {
- //设置状态栏黑色字体图标
- QMUIStatusBarHelper.setStatusBarLightMode(this);
-
String userName = (String) SaveKeyValues.getValue("userName", "");
String userPassword = (String) SaveKeyValues.getValue("userPassword", "");
+ userNameView.setText(userName);
+ userPasswordView.setText(userPassword);
if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) {
- userNameView.setText(userName);
- userPasswordView.setText(userPassword);
+ rememberPasswordView.setChecked(true);
+ } else {
+ rememberPasswordView.setChecked(false);
}
+ rememberPasswordView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (!isChecked) {
+ SaveKeyValues.removeKey("userPassword");
+ }
+ }
+ });
loadingDialog = new QMUITipDialog.Builder(this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
.setTipWord("登陆中,请稍后")
@@ -124,14 +123,9 @@
public void onClick(View v) {
switch (v.getId()) {
case R.id.loginButton:
- userName = userNameView.getText().toString();
- userPassword = userPasswordView.getText().toString();
- if (rememberPasswordView.isChecked()) {
- SaveKeyValues.putValue("userName", userName);
- SaveKeyValues.putValue("userPassword", userPassword);
- }
//密码登录前需要验证sid
authenticatePresenter.onReadyRetrofitRequest();
+ isPasswordLogin = true;
break;
case R.id.changeLoginModeView:
//首次登录不可用扫码,因为还未注册
@@ -169,50 +163,19 @@
}
private void captureFaceData() {
- //TODO 调相机,捕获人脸数据,并保存为文件得到路径
- PictureSelector.create(this)
- .openCamera(PictureMimeType.ofImage())
- .imageEngine(GlideLoadEngine.createGlideEngine())
- .maxSelectNum(1)
- .forResult(PictureConfig.REQUEST_CAMERA);
+ // 调相机,捕获人脸数据,并保存为文件得到路径
+ startActivityForResult(new Intent(this, FacePreViewActivity.class), Constant.FACE_DETECTOR_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
- if (requestCode == PictureConfig.REQUEST_CAMERA) {
- LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0);
- Luban.with(this)
- .load(localMedia.getRealPath())
- .ignoreBy(100)
- .setTargetDir(FileUtils.getFileDir("CompressImageFile"))
- .filter(new CompressionPredicate() {
- @Override
- public boolean apply(String path) {
- return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));
- }
- })
- .setCompressListener(new OnCompressListener() {
- @Override
- public void onStart() {
- // TODO 压缩开始前调用,可以在方法内启动 loading UI
- }
-
- @Override
- public void onSuccess(File file) {
- String imageToBase64 = StringHelper.imageToBase64(file);
-
- ImageBean imageBean = new ImageBean();
- imageBean.setImage(imageToBase64);
- faceLoginPresenter.onReadyRetrofitRequest(imageBean);
- }
-
- @Override
- public void onError(Throwable e) {
- // TODO 当压缩过程出现问题时调用
- }
- }).launch();
+ if (requestCode == Constant.FACE_DETECTOR_CODE) {
+ String imageToBase64 = data.getStringExtra("imageToBase64");
+ ImageBean imageBean = new ImageBean();
+ imageBean.setImage(imageToBase64);
+ faceLoginPresenter.onReadyRetrofitRequest(imageBean);
}
}
}
@@ -232,7 +195,7 @@
.setPlaySound(true)//是否扫描成功后bi~的声音
.setDingPath(R.raw.qrcode)//设置提示音(不设置为默认的Ding~)
.setIsOnlyCenter(true)//是否只识别框中内容(默认为全屏识别)
- .setTitleBackgroudColor(Color.parseColor("#262020"))//设置状态栏颜色
+ .setTitleBackgroudColor(R.color.black)//设置状态栏颜色
.setTitleTextColor(Color.WHITE)//设置Title文字颜色
.setScreenOrientation(QrConfig.SCREEN_PORTRAIT)//设置屏幕方式
.setScanLineStyle(ScanLineView.style_hybrid)//扫描线样式
@@ -241,8 +204,8 @@
QrManager.getInstance().init(qrConfig).startScan(this, new QrManager.OnScanResultCallback() {
@Override
public void onScanSuccess(final ScanResult result) {
-// Log.d(TAG, "扫码结果: " + result.content);
- qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), result.content);
+ qrCode = result.content;
+ authenticatePresenter.onReadyRetrofitRequest();//需要时时保持最新token,所以扫码登录之前需要获取最新token
}
});
}
@@ -254,9 +217,15 @@
@Override
public void authenticateResult(PublicKeyBean result) {
- Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
+// Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
if (result.isSuccess()) {
PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey());
+ String userName = userNameView.getText().toString();
+ String userPassword = userPasswordView.getText().toString();
+ if (rememberPasswordView.isChecked()) {
+ SaveKeyValues.putValue("userName", userName);
+ SaveKeyValues.putValue("userPassword", userPassword);
+ }
if (TextUtils.isEmpty(userName)) {
Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show();
return;
@@ -266,7 +235,6 @@
return;
}
String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey);
- Log.d(TAG, "authenticateResult: 验证成功,开始登录");
//登录并获取Token,POST请求
loginPresenter.onReadyRetrofitRequest(result.getData().getSid(), userName, dataByPublicKey);
} else {
@@ -283,11 +251,14 @@
String token = result.getData().getToken();
if (!TextUtils.isEmpty(token)) {
//获取用户信息
- Log.d(TAG, "obtainLoginResult: 获取Token成功");
TokenHelper.saveToken(token);
//验证成功登录
- startActivity(new Intent(this, MainActivity.class));
- finish();
+ if (isPasswordLogin) {
+ startActivity(new Intent(this, MainActivity.class));
+ finish();
+ } else {
+ qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), qrCode);
+ }
}
}
@@ -307,15 +278,17 @@
}
@Override
- public void obtainFaceLoginData(FaceLoginResultBean resultBean) {
-// Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
- if (resultBean.getCode() == 200) {
+ public void obtainFaceLoginData(FaceResultBean resultBean) {
+ Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
+ if (resultBean.isSuccess()) {
+ //{"code":200,"data":{"kaptcha":"","token":"9135bcb7-4f39-4b7a-a10e-555406ddb9e1"},"exceptionClazz":"","message":"登录成功","success":true}
TokenHelper.saveToken(resultBean.getData().getToken());
//验证成功登录
startActivity(new Intent(this, MainActivity.class));
finish();
} else {
- Toast.makeText(this, "无法解析人脸", Toast.LENGTH_SHORT).show();
+ //{"code":200,"data":"","exceptionClazz":"","message":"图片中没有人脸","success":false}
+ Toast.makeText(this, "人脸识别失败", Toast.LENGTH_SHORT).show();
}
}
@@ -336,5 +309,8 @@
if (qrCodePresenter != null) {
qrCodePresenter.disposeRetrofitRequest();
}
+ if (faceLoginPresenter != null) {
+ faceLoginPresenter.disposeRetrofitRequest();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
index e8e9b75..759a94d 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
@@ -9,4 +9,5 @@
Manifest.permission.WRITE_EXTERNAL_STORAGE};
public static final int PERMISSIONS_CODE = 999;
+ public static final int FACE_DETECTOR_CODE = 998;
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
new file mode 100644
index 0000000..b774ee9
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
@@ -0,0 +1,95 @@
+package com.casic.birmm.hxrq.utils;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.ImageFormat;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.YuvImage;
+import android.util.Base64;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class ImageHelper {
+
+ public ImageHelper(Context context) {
+
+ }
+
+ public Bitmap nv21ToBitmap(byte[] nv21, int width, int height) {
+ Bitmap bitmap = null;
+ try {
+ final YuvImage image = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ image.compressToJpeg(new Rect(0, 0, width, height), 80, outputStream);
+ final Bitmap bmp = BitmapFactory.decodeByteArray(outputStream.toByteArray(), 0, outputStream.size());
+ bitmap = rotateImageView(-90, bmp);
+ outputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return bitmap;
+ }
+
+ public Bitmap rotateImageView(int angle, Bitmap bitmap) {
+ //旋转图片 动作
+ Matrix matrix = new Matrix();
+ matrix.postRotate(angle);
+ // 创建新的图片
+ return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(File file) {
+ if (file == null) {
+ return null;
+ }
+ try {
+ FileInputStream fis = new FileInputStream(file);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] b = new byte[1024];
+ int n;
+ while ((n = fis.read(b)) != -1) {
+ bos.write(b, 0, n);
+ }
+ fis.close();
+ bos.close();
+
+ byte[] imgBytes = bos.toByteArray();
+ String result = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(Bitmap bitmap) {
+ if (bitmap == null) {
+ return null;
+ }
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);//压缩质量
+
+ outputStream.flush();
+ outputStream.close();
+
+ byte[] bitmapBytes = outputStream.toByteArray();
+ String result = Base64.encodeToString(bitmapBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (IOException e) {
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
index f4af6a5..e7772dd 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
@@ -3,33 +3,26 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
-import android.util.Log;
public class SaveKeyValues {
- private static final String TAG = "SaveKeyValues";
-
- @SuppressLint({"StaticFieldLeak"})
- private static Context context;
private static SharedPreferences sharedPreferences;
private static SharedPreferences.Editor editor;
- private static String fileName;
+ @SuppressLint("CommitPrefEdits")
public static void initSharedPreferences(Context mContext) {
- context = mContext.getApplicationContext();
- String packageName = context.getPackageName();
+ String packageName = mContext.getPackageName();
//获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms
String[] split = packageName.split("\\.");//先转义.之后才能分割
int length = split.length;
- fileName = split[length - 1];
- Log.d(TAG, fileName);
+ String fileName = split[length - 1];
+ sharedPreferences = mContext.getSharedPreferences(fileName, Context.MODE_PRIVATE);
+ editor = sharedPreferences.edit();
}
/**
* 存储
*/
public static void putValue(String key, Object object) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
- editor = sharedPreferences.edit();
if (object instanceof String) {
editor.putString(key, (String) object);
} else if (object instanceof Integer) {
@@ -50,7 +43,6 @@
* 获取保存的数据
*/
public static Object getValue(String key, Object defaultObject) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
if (defaultObject instanceof String) {
return sharedPreferences.getString(key, (String) defaultObject);
} else if (defaultObject instanceof Integer) {
@@ -86,7 +78,6 @@
* 查询某个key是否存在
*/
public static boolean containsKey(String key) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
return sharedPreferences.contains(key);
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java
deleted file mode 100644
index 0ebf16a..0000000
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.casic.birmm.hxrq.utils;
-
-import android.util.Base64;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-
-/**
- * @Author: Pengxh
- * @Time: 2021/4/9 15:12
- * @Email: 290677893@qq.com
- **/
-public class StringHelper {
- /**
- * 获取图片base64编码
- */
- public static String imageToBase64(File file) {
- if (file == null) {
- return null;
- }
- try {
- FileInputStream fis = new FileInputStream(file);
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- byte[] b = new byte[1024];
- int n;
- while ((n = fis.read(b)) != -1) {
- bos.write(b, 0, n);
- }
- fis.close();
- bos.close();
-
- byte[] imgBytes = bos.toByteArray();
- String s = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
- return s.replace("-", "+")
- .replace("_", "/");
- } catch (Exception e) {
- return null;
- }
- }
-}
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
index c6d3e33..7e502f2 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
@@ -1,7 +1,11 @@
package com.casic.birmm.hxrq.mvp.view;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
public interface IFaceLoginView {
- void obtainFaceLoginData(FaceLoginResultBean resultBean);
+ void showProgress();
+
+ void hideProgress();
+
+ void obtainFaceLoginData(FaceResultBean resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
index c9783cd..fe666b1 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
@@ -3,6 +3,8 @@
import com.casic.birmm.hxrq.bean.LoginResultBean;
public interface ILoginView {
+ void showProgress();
+
void hideProgress();
void obtainLoginResult(LoginResultBean resultBean);
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
index 4e8821e..4003e26 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
@@ -3,5 +3,9 @@
import com.casic.birmm.hxrq.bean.QrCodeBean;
public interface IQrCodeDataView {
+ void showProgress();
+
+ void hideProgress();
+
void obtainQrCodeData(QrCodeBean userBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
new file mode 100644
index 0000000..4109e3c
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
@@ -0,0 +1,184 @@
+package com.casic.birmm.hxrq.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.ImageFormat;
+import android.hardware.Camera;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import androidx.annotation.NonNull;
+
+import com.casic.birmm.hxrq.R;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.utils.ImageHelper;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Stack;
+
+import butterknife.BindView;
+
+public class FacePreViewActivity extends BaseActivity implements Camera.PreviewCallback {
+
+ private static final int preViewWidth = 720;
+ private static final int preViewHeight = 1280;
+ @BindView(R.id.surfaceView)
+ SurfaceView surfaceView;
+ private SurfaceHolder mSurfaceHolder;
+ private Camera mCamera;
+ private ImageHelper imageHelper;
+ private Stack bitmapStack;
+ private boolean isCanLogin = true;
+
+ @Override
+ public int initLayoutView() {
+ return R.layout.activity_face;
+ }
+
+ @Override
+ protected void setupTopBarLayout() {
+
+ }
+
+ @Override
+ public void initData() {
+ imageHelper = new ImageHelper(this);
+ bitmapStack = new Stack<>();
+ }
+
+ @Override
+ public void initEvent() {
+ // 绑定SurfaceView,取得SurfaceHolder对象
+ mSurfaceHolder = surfaceView.getHolder();
+ mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(@NonNull SurfaceHolder holder) {
+ if (mCamera == null) {
+ //打开相机
+ openCamera();
+ }
+ try {
+ //预览画面
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ //开始预览
+ mCamera.startPreview();
+ }
+
+ @Override
+ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
+
+ }
+
+ @Override
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+ releaseCamera(); //释放相机资源
+ }
+ });
+ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置
+ }
+
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ camera.addCallbackBuffer(data);
+ Camera.Size size = camera.getParameters().getPreviewSize();//必须是相机支持的预览尺寸,否则颜色YUV空间会错位
+ Bitmap originBitmap = imageHelper.nv21ToBitmap(data, size.width, size.height);
+ //要使用Android内置的人脸识别,需要将Bitmap对象转为RGB_565格式,否则无法识别
+// Bitmap faceDetectorBitmap = originBitmap.copy(Bitmap.Config.RGB_565, true);
+// FaceDetector.Face[] faces = new FaceDetector.Face[1];
+// FaceDetector faceDetector = new FaceDetector(faceDetectorBitmap.getWidth(), faceDetectorBitmap.getHeight(), 1);
+// int faceSum = faceDetector.findFaces(faceDetectorBitmap, faces);
+// if (faceSum == 1) {
+ bitmapStack.push(originBitmap);
+ if (bitmapStack.size() >= 5) {//当栈里有5张bitmap之后才开始识别
+ if (isCanLogin) {
+ isCanLogin = false;
+ Bitmap bitmap = bitmapStack.pop();
+ Intent intent = new Intent();
+ intent.putExtra("imageToBase64", ImageHelper.imageToBase64(bitmap));
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ } else {
+ finish();
+ }
+ }
+// } else {
+// Log.d(TAG, "detectorFace: 未检测到人脸");
+// }
+ }
+
+ /**
+ * 打开相机
+ */
+ private void openCamera() {
+ try {
+ mCamera = Camera.open(1);
+ initParameters(mCamera); //初始化相机配置信息
+ mCamera.setPreviewCallback(this);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 初始化相机属性
+ */
+ private void initParameters(Camera camera) {
+ try {
+ Camera.Parameters mParameters = camera.getParameters();
+ mParameters.setPreviewFormat(ImageFormat.NV21); //设置预览图片的格式
+ //获取与指定宽高相等或最接近的尺寸
+ //设置预览尺寸
+ Camera.Size bestPreviewSize = obtainBestSize(preViewWidth, preViewHeight, mParameters.getSupportedPreviewSizes());
+ mParameters.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height);
+ //设置保存图片尺寸
+// Camera.Size bestPicSize = obtainBestSize(picWidth, picHeight, mParameters.getSupportedPictureSizes());
+// mParameters.setPictureSize(bestPicSize.width, bestPicSize.height);
+ //对焦模式
+ mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ camera.setDisplayOrientation(90);
+ camera.setParameters(mParameters);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 获取最合适的尺寸
+ */
+ private Camera.Size obtainBestSize(int targetWidth, int targetHeight, List sizeList) {
+ Camera.Size bestSize = null;
+ int targetRatio = targetHeight / targetWidth;//目标大小的宽高比
+ int minDiff = targetRatio;
+
+ for (Camera.Size size : sizeList) {
+ if (size.width == targetHeight && size.height == targetWidth) {
+ bestSize = size;
+ break;
+ }
+ int supportedRatio = (size.width / size.height);
+ if (Math.abs(supportedRatio - targetRatio) < minDiff) {
+ minDiff = Math.abs(supportedRatio - targetRatio);
+ bestSize = size;
+ }
+ }
+ return bestSize;
+ }
+
+ /**
+ * 释放相机资源
+ */
+ private void releaseCamera() {
+ if (mCamera != null) {
+ mCamera.stopPreview();
+ mCamera.setPreviewCallback(null);
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
index 98aef9d..30c26c8 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
@@ -8,14 +8,15 @@
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.casic.birmm.hxrq.R;
-import com.casic.birmm.hxrq.base.DoubleClickExitActivity;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -28,23 +29,16 @@
import com.casic.birmm.hxrq.mvp.view.IFaceLoginView;
import com.casic.birmm.hxrq.mvp.view.ILoginView;
import com.casic.birmm.hxrq.mvp.view.IQrCodeDataView;
-import com.casic.birmm.hxrq.utils.FileUtils;
-import com.casic.birmm.hxrq.utils.GlideLoadEngine;
+import com.casic.birmm.hxrq.utils.Constant;
import com.casic.birmm.hxrq.utils.RSAUtils;
import com.casic.birmm.hxrq.utils.SaveKeyValues;
-import com.casic.birmm.hxrq.utils.StringHelper;
import com.casic.birmm.hxrq.utils.TokenHelper;
import com.google.gson.Gson;
-import com.luck.picture.lib.PictureSelector;
-import com.luck.picture.lib.config.PictureConfig;
-import com.luck.picture.lib.config.PictureMimeType;
-import com.luck.picture.lib.entity.LocalMedia;
import com.qmuiteam.qmui.util.QMUIStatusBarHelper;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton;
-import java.io.File;
import java.security.PublicKey;
import butterknife.BindView;
@@ -53,15 +47,11 @@
import cn.bertsir.zbar.QrConfig;
import cn.bertsir.zbar.QrManager;
import cn.bertsir.zbar.view.ScanLineView;
-import top.zibin.luban.CompressionPredicate;
-import top.zibin.luban.Luban;
-import top.zibin.luban.OnCompressListener;
-public class LoginActivity extends DoubleClickExitActivity
- implements View.OnClickListener, IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
+public class LoginActivity extends BaseActivity implements View.OnClickListener,
+ IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
private static final String TAG = "LoginActivity";
-
@BindView(R.id.userNameView)
EditText userNameView;
@BindView(R.id.userPasswordView)
@@ -76,8 +66,8 @@
private LoginPresenterImpl loginPresenter;
private QrCodePresenterImpl qrCodePresenter;
private FaceLoginPresenterImpl faceLoginPresenter;
- private String userName;
- private String userPassword;
+ private boolean isPasswordLogin = false;
+ private String qrCode = "";
@Override
public int initLayoutView() {
@@ -86,20 +76,29 @@
@Override
protected void setupTopBarLayout() {
- //TODO 此页面无需实现
+ //设置状态栏黑色字体图标
+ QMUIStatusBarHelper.setStatusBarLightMode(this);
}
@Override
public void initData() {
- //设置状态栏黑色字体图标
- QMUIStatusBarHelper.setStatusBarLightMode(this);
-
String userName = (String) SaveKeyValues.getValue("userName", "");
String userPassword = (String) SaveKeyValues.getValue("userPassword", "");
+ userNameView.setText(userName);
+ userPasswordView.setText(userPassword);
if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) {
- userNameView.setText(userName);
- userPasswordView.setText(userPassword);
+ rememberPasswordView.setChecked(true);
+ } else {
+ rememberPasswordView.setChecked(false);
}
+ rememberPasswordView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (!isChecked) {
+ SaveKeyValues.removeKey("userPassword");
+ }
+ }
+ });
loadingDialog = new QMUITipDialog.Builder(this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
.setTipWord("登陆中,请稍后")
@@ -124,14 +123,9 @@
public void onClick(View v) {
switch (v.getId()) {
case R.id.loginButton:
- userName = userNameView.getText().toString();
- userPassword = userPasswordView.getText().toString();
- if (rememberPasswordView.isChecked()) {
- SaveKeyValues.putValue("userName", userName);
- SaveKeyValues.putValue("userPassword", userPassword);
- }
//密码登录前需要验证sid
authenticatePresenter.onReadyRetrofitRequest();
+ isPasswordLogin = true;
break;
case R.id.changeLoginModeView:
//首次登录不可用扫码,因为还未注册
@@ -169,50 +163,19 @@
}
private void captureFaceData() {
- //TODO 调相机,捕获人脸数据,并保存为文件得到路径
- PictureSelector.create(this)
- .openCamera(PictureMimeType.ofImage())
- .imageEngine(GlideLoadEngine.createGlideEngine())
- .maxSelectNum(1)
- .forResult(PictureConfig.REQUEST_CAMERA);
+ // 调相机,捕获人脸数据,并保存为文件得到路径
+ startActivityForResult(new Intent(this, FacePreViewActivity.class), Constant.FACE_DETECTOR_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
- if (requestCode == PictureConfig.REQUEST_CAMERA) {
- LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0);
- Luban.with(this)
- .load(localMedia.getRealPath())
- .ignoreBy(100)
- .setTargetDir(FileUtils.getFileDir("CompressImageFile"))
- .filter(new CompressionPredicate() {
- @Override
- public boolean apply(String path) {
- return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));
- }
- })
- .setCompressListener(new OnCompressListener() {
- @Override
- public void onStart() {
- // TODO 压缩开始前调用,可以在方法内启动 loading UI
- }
-
- @Override
- public void onSuccess(File file) {
- String imageToBase64 = StringHelper.imageToBase64(file);
-
- ImageBean imageBean = new ImageBean();
- imageBean.setImage(imageToBase64);
- faceLoginPresenter.onReadyRetrofitRequest(imageBean);
- }
-
- @Override
- public void onError(Throwable e) {
- // TODO 当压缩过程出现问题时调用
- }
- }).launch();
+ if (requestCode == Constant.FACE_DETECTOR_CODE) {
+ String imageToBase64 = data.getStringExtra("imageToBase64");
+ ImageBean imageBean = new ImageBean();
+ imageBean.setImage(imageToBase64);
+ faceLoginPresenter.onReadyRetrofitRequest(imageBean);
}
}
}
@@ -232,7 +195,7 @@
.setPlaySound(true)//是否扫描成功后bi~的声音
.setDingPath(R.raw.qrcode)//设置提示音(不设置为默认的Ding~)
.setIsOnlyCenter(true)//是否只识别框中内容(默认为全屏识别)
- .setTitleBackgroudColor(Color.parseColor("#262020"))//设置状态栏颜色
+ .setTitleBackgroudColor(R.color.black)//设置状态栏颜色
.setTitleTextColor(Color.WHITE)//设置Title文字颜色
.setScreenOrientation(QrConfig.SCREEN_PORTRAIT)//设置屏幕方式
.setScanLineStyle(ScanLineView.style_hybrid)//扫描线样式
@@ -241,8 +204,8 @@
QrManager.getInstance().init(qrConfig).startScan(this, new QrManager.OnScanResultCallback() {
@Override
public void onScanSuccess(final ScanResult result) {
-// Log.d(TAG, "扫码结果: " + result.content);
- qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), result.content);
+ qrCode = result.content;
+ authenticatePresenter.onReadyRetrofitRequest();//需要时时保持最新token,所以扫码登录之前需要获取最新token
}
});
}
@@ -254,9 +217,15 @@
@Override
public void authenticateResult(PublicKeyBean result) {
- Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
+// Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
if (result.isSuccess()) {
PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey());
+ String userName = userNameView.getText().toString();
+ String userPassword = userPasswordView.getText().toString();
+ if (rememberPasswordView.isChecked()) {
+ SaveKeyValues.putValue("userName", userName);
+ SaveKeyValues.putValue("userPassword", userPassword);
+ }
if (TextUtils.isEmpty(userName)) {
Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show();
return;
@@ -266,7 +235,6 @@
return;
}
String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey);
- Log.d(TAG, "authenticateResult: 验证成功,开始登录");
//登录并获取Token,POST请求
loginPresenter.onReadyRetrofitRequest(result.getData().getSid(), userName, dataByPublicKey);
} else {
@@ -283,11 +251,14 @@
String token = result.getData().getToken();
if (!TextUtils.isEmpty(token)) {
//获取用户信息
- Log.d(TAG, "obtainLoginResult: 获取Token成功");
TokenHelper.saveToken(token);
//验证成功登录
- startActivity(new Intent(this, MainActivity.class));
- finish();
+ if (isPasswordLogin) {
+ startActivity(new Intent(this, MainActivity.class));
+ finish();
+ } else {
+ qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), qrCode);
+ }
}
}
@@ -307,15 +278,17 @@
}
@Override
- public void obtainFaceLoginData(FaceLoginResultBean resultBean) {
-// Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
- if (resultBean.getCode() == 200) {
+ public void obtainFaceLoginData(FaceResultBean resultBean) {
+ Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
+ if (resultBean.isSuccess()) {
+ //{"code":200,"data":{"kaptcha":"","token":"9135bcb7-4f39-4b7a-a10e-555406ddb9e1"},"exceptionClazz":"","message":"登录成功","success":true}
TokenHelper.saveToken(resultBean.getData().getToken());
//验证成功登录
startActivity(new Intent(this, MainActivity.class));
finish();
} else {
- Toast.makeText(this, "无法解析人脸", Toast.LENGTH_SHORT).show();
+ //{"code":200,"data":"","exceptionClazz":"","message":"图片中没有人脸","success":false}
+ Toast.makeText(this, "人脸识别失败", Toast.LENGTH_SHORT).show();
}
}
@@ -336,5 +309,8 @@
if (qrCodePresenter != null) {
qrCodePresenter.disposeRetrofitRequest();
}
+ if (faceLoginPresenter != null) {
+ faceLoginPresenter.disposeRetrofitRequest();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
index e8e9b75..759a94d 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
@@ -9,4 +9,5 @@
Manifest.permission.WRITE_EXTERNAL_STORAGE};
public static final int PERMISSIONS_CODE = 999;
+ public static final int FACE_DETECTOR_CODE = 998;
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
new file mode 100644
index 0000000..b774ee9
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
@@ -0,0 +1,95 @@
+package com.casic.birmm.hxrq.utils;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.ImageFormat;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.YuvImage;
+import android.util.Base64;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class ImageHelper {
+
+ public ImageHelper(Context context) {
+
+ }
+
+ public Bitmap nv21ToBitmap(byte[] nv21, int width, int height) {
+ Bitmap bitmap = null;
+ try {
+ final YuvImage image = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ image.compressToJpeg(new Rect(0, 0, width, height), 80, outputStream);
+ final Bitmap bmp = BitmapFactory.decodeByteArray(outputStream.toByteArray(), 0, outputStream.size());
+ bitmap = rotateImageView(-90, bmp);
+ outputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return bitmap;
+ }
+
+ public Bitmap rotateImageView(int angle, Bitmap bitmap) {
+ //旋转图片 动作
+ Matrix matrix = new Matrix();
+ matrix.postRotate(angle);
+ // 创建新的图片
+ return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(File file) {
+ if (file == null) {
+ return null;
+ }
+ try {
+ FileInputStream fis = new FileInputStream(file);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] b = new byte[1024];
+ int n;
+ while ((n = fis.read(b)) != -1) {
+ bos.write(b, 0, n);
+ }
+ fis.close();
+ bos.close();
+
+ byte[] imgBytes = bos.toByteArray();
+ String result = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(Bitmap bitmap) {
+ if (bitmap == null) {
+ return null;
+ }
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);//压缩质量
+
+ outputStream.flush();
+ outputStream.close();
+
+ byte[] bitmapBytes = outputStream.toByteArray();
+ String result = Base64.encodeToString(bitmapBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (IOException e) {
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
index f4af6a5..e7772dd 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
@@ -3,33 +3,26 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
-import android.util.Log;
public class SaveKeyValues {
- private static final String TAG = "SaveKeyValues";
-
- @SuppressLint({"StaticFieldLeak"})
- private static Context context;
private static SharedPreferences sharedPreferences;
private static SharedPreferences.Editor editor;
- private static String fileName;
+ @SuppressLint("CommitPrefEdits")
public static void initSharedPreferences(Context mContext) {
- context = mContext.getApplicationContext();
- String packageName = context.getPackageName();
+ String packageName = mContext.getPackageName();
//获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms
String[] split = packageName.split("\\.");//先转义.之后才能分割
int length = split.length;
- fileName = split[length - 1];
- Log.d(TAG, fileName);
+ String fileName = split[length - 1];
+ sharedPreferences = mContext.getSharedPreferences(fileName, Context.MODE_PRIVATE);
+ editor = sharedPreferences.edit();
}
/**
* 存储
*/
public static void putValue(String key, Object object) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
- editor = sharedPreferences.edit();
if (object instanceof String) {
editor.putString(key, (String) object);
} else if (object instanceof Integer) {
@@ -50,7 +43,6 @@
* 获取保存的数据
*/
public static Object getValue(String key, Object defaultObject) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
if (defaultObject instanceof String) {
return sharedPreferences.getString(key, (String) defaultObject);
} else if (defaultObject instanceof Integer) {
@@ -86,7 +78,6 @@
* 查询某个key是否存在
*/
public static boolean containsKey(String key) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
return sharedPreferences.contains(key);
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java
deleted file mode 100644
index 0ebf16a..0000000
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.casic.birmm.hxrq.utils;
-
-import android.util.Base64;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-
-/**
- * @Author: Pengxh
- * @Time: 2021/4/9 15:12
- * @Email: 290677893@qq.com
- **/
-public class StringHelper {
- /**
- * 获取图片base64编码
- */
- public static String imageToBase64(File file) {
- if (file == null) {
- return null;
- }
- try {
- FileInputStream fis = new FileInputStream(file);
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- byte[] b = new byte[1024];
- int n;
- while ((n = fis.read(b)) != -1) {
- bos.write(b, 0, n);
- }
- fis.close();
- bos.close();
-
- byte[] imgBytes = bos.toByteArray();
- String s = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
- return s.replace("-", "+")
- .replace("_", "/");
- } catch (Exception e) {
- return null;
- }
- }
-}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
index 8fe5264..1de1ff4 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.utils.retrofit;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -49,6 +49,6 @@
*/
@Headers({"Content-Type: application/json"})
@POST("/cockpit/face/login")
- Observable getFaceLoginResult(
+ Observable getFaceLoginResult(
@Body ImageBean imageBean);
}
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
index c6d3e33..7e502f2 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
@@ -1,7 +1,11 @@
package com.casic.birmm.hxrq.mvp.view;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
public interface IFaceLoginView {
- void obtainFaceLoginData(FaceLoginResultBean resultBean);
+ void showProgress();
+
+ void hideProgress();
+
+ void obtainFaceLoginData(FaceResultBean resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
index c9783cd..fe666b1 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
@@ -3,6 +3,8 @@
import com.casic.birmm.hxrq.bean.LoginResultBean;
public interface ILoginView {
+ void showProgress();
+
void hideProgress();
void obtainLoginResult(LoginResultBean resultBean);
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
index 4e8821e..4003e26 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
@@ -3,5 +3,9 @@
import com.casic.birmm.hxrq.bean.QrCodeBean;
public interface IQrCodeDataView {
+ void showProgress();
+
+ void hideProgress();
+
void obtainQrCodeData(QrCodeBean userBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
new file mode 100644
index 0000000..4109e3c
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
@@ -0,0 +1,184 @@
+package com.casic.birmm.hxrq.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.ImageFormat;
+import android.hardware.Camera;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import androidx.annotation.NonNull;
+
+import com.casic.birmm.hxrq.R;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.utils.ImageHelper;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Stack;
+
+import butterknife.BindView;
+
+public class FacePreViewActivity extends BaseActivity implements Camera.PreviewCallback {
+
+ private static final int preViewWidth = 720;
+ private static final int preViewHeight = 1280;
+ @BindView(R.id.surfaceView)
+ SurfaceView surfaceView;
+ private SurfaceHolder mSurfaceHolder;
+ private Camera mCamera;
+ private ImageHelper imageHelper;
+ private Stack bitmapStack;
+ private boolean isCanLogin = true;
+
+ @Override
+ public int initLayoutView() {
+ return R.layout.activity_face;
+ }
+
+ @Override
+ protected void setupTopBarLayout() {
+
+ }
+
+ @Override
+ public void initData() {
+ imageHelper = new ImageHelper(this);
+ bitmapStack = new Stack<>();
+ }
+
+ @Override
+ public void initEvent() {
+ // 绑定SurfaceView,取得SurfaceHolder对象
+ mSurfaceHolder = surfaceView.getHolder();
+ mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(@NonNull SurfaceHolder holder) {
+ if (mCamera == null) {
+ //打开相机
+ openCamera();
+ }
+ try {
+ //预览画面
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ //开始预览
+ mCamera.startPreview();
+ }
+
+ @Override
+ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
+
+ }
+
+ @Override
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+ releaseCamera(); //释放相机资源
+ }
+ });
+ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置
+ }
+
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ camera.addCallbackBuffer(data);
+ Camera.Size size = camera.getParameters().getPreviewSize();//必须是相机支持的预览尺寸,否则颜色YUV空间会错位
+ Bitmap originBitmap = imageHelper.nv21ToBitmap(data, size.width, size.height);
+ //要使用Android内置的人脸识别,需要将Bitmap对象转为RGB_565格式,否则无法识别
+// Bitmap faceDetectorBitmap = originBitmap.copy(Bitmap.Config.RGB_565, true);
+// FaceDetector.Face[] faces = new FaceDetector.Face[1];
+// FaceDetector faceDetector = new FaceDetector(faceDetectorBitmap.getWidth(), faceDetectorBitmap.getHeight(), 1);
+// int faceSum = faceDetector.findFaces(faceDetectorBitmap, faces);
+// if (faceSum == 1) {
+ bitmapStack.push(originBitmap);
+ if (bitmapStack.size() >= 5) {//当栈里有5张bitmap之后才开始识别
+ if (isCanLogin) {
+ isCanLogin = false;
+ Bitmap bitmap = bitmapStack.pop();
+ Intent intent = new Intent();
+ intent.putExtra("imageToBase64", ImageHelper.imageToBase64(bitmap));
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ } else {
+ finish();
+ }
+ }
+// } else {
+// Log.d(TAG, "detectorFace: 未检测到人脸");
+// }
+ }
+
+ /**
+ * 打开相机
+ */
+ private void openCamera() {
+ try {
+ mCamera = Camera.open(1);
+ initParameters(mCamera); //初始化相机配置信息
+ mCamera.setPreviewCallback(this);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 初始化相机属性
+ */
+ private void initParameters(Camera camera) {
+ try {
+ Camera.Parameters mParameters = camera.getParameters();
+ mParameters.setPreviewFormat(ImageFormat.NV21); //设置预览图片的格式
+ //获取与指定宽高相等或最接近的尺寸
+ //设置预览尺寸
+ Camera.Size bestPreviewSize = obtainBestSize(preViewWidth, preViewHeight, mParameters.getSupportedPreviewSizes());
+ mParameters.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height);
+ //设置保存图片尺寸
+// Camera.Size bestPicSize = obtainBestSize(picWidth, picHeight, mParameters.getSupportedPictureSizes());
+// mParameters.setPictureSize(bestPicSize.width, bestPicSize.height);
+ //对焦模式
+ mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ camera.setDisplayOrientation(90);
+ camera.setParameters(mParameters);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 获取最合适的尺寸
+ */
+ private Camera.Size obtainBestSize(int targetWidth, int targetHeight, List sizeList) {
+ Camera.Size bestSize = null;
+ int targetRatio = targetHeight / targetWidth;//目标大小的宽高比
+ int minDiff = targetRatio;
+
+ for (Camera.Size size : sizeList) {
+ if (size.width == targetHeight && size.height == targetWidth) {
+ bestSize = size;
+ break;
+ }
+ int supportedRatio = (size.width / size.height);
+ if (Math.abs(supportedRatio - targetRatio) < minDiff) {
+ minDiff = Math.abs(supportedRatio - targetRatio);
+ bestSize = size;
+ }
+ }
+ return bestSize;
+ }
+
+ /**
+ * 释放相机资源
+ */
+ private void releaseCamera() {
+ if (mCamera != null) {
+ mCamera.stopPreview();
+ mCamera.setPreviewCallback(null);
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
index 98aef9d..30c26c8 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
@@ -8,14 +8,15 @@
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.casic.birmm.hxrq.R;
-import com.casic.birmm.hxrq.base.DoubleClickExitActivity;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -28,23 +29,16 @@
import com.casic.birmm.hxrq.mvp.view.IFaceLoginView;
import com.casic.birmm.hxrq.mvp.view.ILoginView;
import com.casic.birmm.hxrq.mvp.view.IQrCodeDataView;
-import com.casic.birmm.hxrq.utils.FileUtils;
-import com.casic.birmm.hxrq.utils.GlideLoadEngine;
+import com.casic.birmm.hxrq.utils.Constant;
import com.casic.birmm.hxrq.utils.RSAUtils;
import com.casic.birmm.hxrq.utils.SaveKeyValues;
-import com.casic.birmm.hxrq.utils.StringHelper;
import com.casic.birmm.hxrq.utils.TokenHelper;
import com.google.gson.Gson;
-import com.luck.picture.lib.PictureSelector;
-import com.luck.picture.lib.config.PictureConfig;
-import com.luck.picture.lib.config.PictureMimeType;
-import com.luck.picture.lib.entity.LocalMedia;
import com.qmuiteam.qmui.util.QMUIStatusBarHelper;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton;
-import java.io.File;
import java.security.PublicKey;
import butterknife.BindView;
@@ -53,15 +47,11 @@
import cn.bertsir.zbar.QrConfig;
import cn.bertsir.zbar.QrManager;
import cn.bertsir.zbar.view.ScanLineView;
-import top.zibin.luban.CompressionPredicate;
-import top.zibin.luban.Luban;
-import top.zibin.luban.OnCompressListener;
-public class LoginActivity extends DoubleClickExitActivity
- implements View.OnClickListener, IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
+public class LoginActivity extends BaseActivity implements View.OnClickListener,
+ IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
private static final String TAG = "LoginActivity";
-
@BindView(R.id.userNameView)
EditText userNameView;
@BindView(R.id.userPasswordView)
@@ -76,8 +66,8 @@
private LoginPresenterImpl loginPresenter;
private QrCodePresenterImpl qrCodePresenter;
private FaceLoginPresenterImpl faceLoginPresenter;
- private String userName;
- private String userPassword;
+ private boolean isPasswordLogin = false;
+ private String qrCode = "";
@Override
public int initLayoutView() {
@@ -86,20 +76,29 @@
@Override
protected void setupTopBarLayout() {
- //TODO 此页面无需实现
+ //设置状态栏黑色字体图标
+ QMUIStatusBarHelper.setStatusBarLightMode(this);
}
@Override
public void initData() {
- //设置状态栏黑色字体图标
- QMUIStatusBarHelper.setStatusBarLightMode(this);
-
String userName = (String) SaveKeyValues.getValue("userName", "");
String userPassword = (String) SaveKeyValues.getValue("userPassword", "");
+ userNameView.setText(userName);
+ userPasswordView.setText(userPassword);
if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) {
- userNameView.setText(userName);
- userPasswordView.setText(userPassword);
+ rememberPasswordView.setChecked(true);
+ } else {
+ rememberPasswordView.setChecked(false);
}
+ rememberPasswordView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (!isChecked) {
+ SaveKeyValues.removeKey("userPassword");
+ }
+ }
+ });
loadingDialog = new QMUITipDialog.Builder(this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
.setTipWord("登陆中,请稍后")
@@ -124,14 +123,9 @@
public void onClick(View v) {
switch (v.getId()) {
case R.id.loginButton:
- userName = userNameView.getText().toString();
- userPassword = userPasswordView.getText().toString();
- if (rememberPasswordView.isChecked()) {
- SaveKeyValues.putValue("userName", userName);
- SaveKeyValues.putValue("userPassword", userPassword);
- }
//密码登录前需要验证sid
authenticatePresenter.onReadyRetrofitRequest();
+ isPasswordLogin = true;
break;
case R.id.changeLoginModeView:
//首次登录不可用扫码,因为还未注册
@@ -169,50 +163,19 @@
}
private void captureFaceData() {
- //TODO 调相机,捕获人脸数据,并保存为文件得到路径
- PictureSelector.create(this)
- .openCamera(PictureMimeType.ofImage())
- .imageEngine(GlideLoadEngine.createGlideEngine())
- .maxSelectNum(1)
- .forResult(PictureConfig.REQUEST_CAMERA);
+ // 调相机,捕获人脸数据,并保存为文件得到路径
+ startActivityForResult(new Intent(this, FacePreViewActivity.class), Constant.FACE_DETECTOR_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
- if (requestCode == PictureConfig.REQUEST_CAMERA) {
- LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0);
- Luban.with(this)
- .load(localMedia.getRealPath())
- .ignoreBy(100)
- .setTargetDir(FileUtils.getFileDir("CompressImageFile"))
- .filter(new CompressionPredicate() {
- @Override
- public boolean apply(String path) {
- return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));
- }
- })
- .setCompressListener(new OnCompressListener() {
- @Override
- public void onStart() {
- // TODO 压缩开始前调用,可以在方法内启动 loading UI
- }
-
- @Override
- public void onSuccess(File file) {
- String imageToBase64 = StringHelper.imageToBase64(file);
-
- ImageBean imageBean = new ImageBean();
- imageBean.setImage(imageToBase64);
- faceLoginPresenter.onReadyRetrofitRequest(imageBean);
- }
-
- @Override
- public void onError(Throwable e) {
- // TODO 当压缩过程出现问题时调用
- }
- }).launch();
+ if (requestCode == Constant.FACE_DETECTOR_CODE) {
+ String imageToBase64 = data.getStringExtra("imageToBase64");
+ ImageBean imageBean = new ImageBean();
+ imageBean.setImage(imageToBase64);
+ faceLoginPresenter.onReadyRetrofitRequest(imageBean);
}
}
}
@@ -232,7 +195,7 @@
.setPlaySound(true)//是否扫描成功后bi~的声音
.setDingPath(R.raw.qrcode)//设置提示音(不设置为默认的Ding~)
.setIsOnlyCenter(true)//是否只识别框中内容(默认为全屏识别)
- .setTitleBackgroudColor(Color.parseColor("#262020"))//设置状态栏颜色
+ .setTitleBackgroudColor(R.color.black)//设置状态栏颜色
.setTitleTextColor(Color.WHITE)//设置Title文字颜色
.setScreenOrientation(QrConfig.SCREEN_PORTRAIT)//设置屏幕方式
.setScanLineStyle(ScanLineView.style_hybrid)//扫描线样式
@@ -241,8 +204,8 @@
QrManager.getInstance().init(qrConfig).startScan(this, new QrManager.OnScanResultCallback() {
@Override
public void onScanSuccess(final ScanResult result) {
-// Log.d(TAG, "扫码结果: " + result.content);
- qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), result.content);
+ qrCode = result.content;
+ authenticatePresenter.onReadyRetrofitRequest();//需要时时保持最新token,所以扫码登录之前需要获取最新token
}
});
}
@@ -254,9 +217,15 @@
@Override
public void authenticateResult(PublicKeyBean result) {
- Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
+// Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
if (result.isSuccess()) {
PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey());
+ String userName = userNameView.getText().toString();
+ String userPassword = userPasswordView.getText().toString();
+ if (rememberPasswordView.isChecked()) {
+ SaveKeyValues.putValue("userName", userName);
+ SaveKeyValues.putValue("userPassword", userPassword);
+ }
if (TextUtils.isEmpty(userName)) {
Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show();
return;
@@ -266,7 +235,6 @@
return;
}
String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey);
- Log.d(TAG, "authenticateResult: 验证成功,开始登录");
//登录并获取Token,POST请求
loginPresenter.onReadyRetrofitRequest(result.getData().getSid(), userName, dataByPublicKey);
} else {
@@ -283,11 +251,14 @@
String token = result.getData().getToken();
if (!TextUtils.isEmpty(token)) {
//获取用户信息
- Log.d(TAG, "obtainLoginResult: 获取Token成功");
TokenHelper.saveToken(token);
//验证成功登录
- startActivity(new Intent(this, MainActivity.class));
- finish();
+ if (isPasswordLogin) {
+ startActivity(new Intent(this, MainActivity.class));
+ finish();
+ } else {
+ qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), qrCode);
+ }
}
}
@@ -307,15 +278,17 @@
}
@Override
- public void obtainFaceLoginData(FaceLoginResultBean resultBean) {
-// Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
- if (resultBean.getCode() == 200) {
+ public void obtainFaceLoginData(FaceResultBean resultBean) {
+ Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
+ if (resultBean.isSuccess()) {
+ //{"code":200,"data":{"kaptcha":"","token":"9135bcb7-4f39-4b7a-a10e-555406ddb9e1"},"exceptionClazz":"","message":"登录成功","success":true}
TokenHelper.saveToken(resultBean.getData().getToken());
//验证成功登录
startActivity(new Intent(this, MainActivity.class));
finish();
} else {
- Toast.makeText(this, "无法解析人脸", Toast.LENGTH_SHORT).show();
+ //{"code":200,"data":"","exceptionClazz":"","message":"图片中没有人脸","success":false}
+ Toast.makeText(this, "人脸识别失败", Toast.LENGTH_SHORT).show();
}
}
@@ -336,5 +309,8 @@
if (qrCodePresenter != null) {
qrCodePresenter.disposeRetrofitRequest();
}
+ if (faceLoginPresenter != null) {
+ faceLoginPresenter.disposeRetrofitRequest();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
index e8e9b75..759a94d 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
@@ -9,4 +9,5 @@
Manifest.permission.WRITE_EXTERNAL_STORAGE};
public static final int PERMISSIONS_CODE = 999;
+ public static final int FACE_DETECTOR_CODE = 998;
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
new file mode 100644
index 0000000..b774ee9
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
@@ -0,0 +1,95 @@
+package com.casic.birmm.hxrq.utils;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.ImageFormat;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.YuvImage;
+import android.util.Base64;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class ImageHelper {
+
+ public ImageHelper(Context context) {
+
+ }
+
+ public Bitmap nv21ToBitmap(byte[] nv21, int width, int height) {
+ Bitmap bitmap = null;
+ try {
+ final YuvImage image = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ image.compressToJpeg(new Rect(0, 0, width, height), 80, outputStream);
+ final Bitmap bmp = BitmapFactory.decodeByteArray(outputStream.toByteArray(), 0, outputStream.size());
+ bitmap = rotateImageView(-90, bmp);
+ outputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return bitmap;
+ }
+
+ public Bitmap rotateImageView(int angle, Bitmap bitmap) {
+ //旋转图片 动作
+ Matrix matrix = new Matrix();
+ matrix.postRotate(angle);
+ // 创建新的图片
+ return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(File file) {
+ if (file == null) {
+ return null;
+ }
+ try {
+ FileInputStream fis = new FileInputStream(file);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] b = new byte[1024];
+ int n;
+ while ((n = fis.read(b)) != -1) {
+ bos.write(b, 0, n);
+ }
+ fis.close();
+ bos.close();
+
+ byte[] imgBytes = bos.toByteArray();
+ String result = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(Bitmap bitmap) {
+ if (bitmap == null) {
+ return null;
+ }
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);//压缩质量
+
+ outputStream.flush();
+ outputStream.close();
+
+ byte[] bitmapBytes = outputStream.toByteArray();
+ String result = Base64.encodeToString(bitmapBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (IOException e) {
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
index f4af6a5..e7772dd 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
@@ -3,33 +3,26 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
-import android.util.Log;
public class SaveKeyValues {
- private static final String TAG = "SaveKeyValues";
-
- @SuppressLint({"StaticFieldLeak"})
- private static Context context;
private static SharedPreferences sharedPreferences;
private static SharedPreferences.Editor editor;
- private static String fileName;
+ @SuppressLint("CommitPrefEdits")
public static void initSharedPreferences(Context mContext) {
- context = mContext.getApplicationContext();
- String packageName = context.getPackageName();
+ String packageName = mContext.getPackageName();
//获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms
String[] split = packageName.split("\\.");//先转义.之后才能分割
int length = split.length;
- fileName = split[length - 1];
- Log.d(TAG, fileName);
+ String fileName = split[length - 1];
+ sharedPreferences = mContext.getSharedPreferences(fileName, Context.MODE_PRIVATE);
+ editor = sharedPreferences.edit();
}
/**
* 存储
*/
public static void putValue(String key, Object object) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
- editor = sharedPreferences.edit();
if (object instanceof String) {
editor.putString(key, (String) object);
} else if (object instanceof Integer) {
@@ -50,7 +43,6 @@
* 获取保存的数据
*/
public static Object getValue(String key, Object defaultObject) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
if (defaultObject instanceof String) {
return sharedPreferences.getString(key, (String) defaultObject);
} else if (defaultObject instanceof Integer) {
@@ -86,7 +78,6 @@
* 查询某个key是否存在
*/
public static boolean containsKey(String key) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
return sharedPreferences.contains(key);
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java
deleted file mode 100644
index 0ebf16a..0000000
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.casic.birmm.hxrq.utils;
-
-import android.util.Base64;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-
-/**
- * @Author: Pengxh
- * @Time: 2021/4/9 15:12
- * @Email: 290677893@qq.com
- **/
-public class StringHelper {
- /**
- * 获取图片base64编码
- */
- public static String imageToBase64(File file) {
- if (file == null) {
- return null;
- }
- try {
- FileInputStream fis = new FileInputStream(file);
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- byte[] b = new byte[1024];
- int n;
- while ((n = fis.read(b)) != -1) {
- bos.write(b, 0, n);
- }
- fis.close();
- bos.close();
-
- byte[] imgBytes = bos.toByteArray();
- String s = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
- return s.replace("-", "+")
- .replace("_", "/");
- } catch (Exception e) {
- return null;
- }
- }
-}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
index 8fe5264..1de1ff4 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.utils.retrofit;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -49,6 +49,6 @@
*/
@Headers({"Content-Type: application/json"})
@POST("/cockpit/face/login")
- Observable getFaceLoginResult(
+ Observable getFaceLoginResult(
@Body ImageBean imageBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java
index ef4307e..d481055 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java
@@ -2,7 +2,7 @@
import android.util.Log;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -10,7 +10,6 @@
import com.casic.birmm.hxrq.utils.HttpConfig;
import org.jetbrains.annotations.NotNull;
-import org.json.JSONObject;
import java.util.concurrent.TimeUnit;
@@ -79,7 +78,7 @@
/**
* 人脸识别登录结果
*/
- public static Observable getFaceResult(String baseUrl, ImageBean imageBean) {
+ public static Observable getFaceResult(String baseUrl, ImageBean imageBean) {
Retrofit retrofit = createRetrofit(baseUrl);
RetrofitService service = retrofit.create(RetrofitService.class);
return service.getFaceLoginResult(imageBean);
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
index c6d3e33..7e502f2 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
@@ -1,7 +1,11 @@
package com.casic.birmm.hxrq.mvp.view;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
public interface IFaceLoginView {
- void obtainFaceLoginData(FaceLoginResultBean resultBean);
+ void showProgress();
+
+ void hideProgress();
+
+ void obtainFaceLoginData(FaceResultBean resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
index c9783cd..fe666b1 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
@@ -3,6 +3,8 @@
import com.casic.birmm.hxrq.bean.LoginResultBean;
public interface ILoginView {
+ void showProgress();
+
void hideProgress();
void obtainLoginResult(LoginResultBean resultBean);
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
index 4e8821e..4003e26 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
@@ -3,5 +3,9 @@
import com.casic.birmm.hxrq.bean.QrCodeBean;
public interface IQrCodeDataView {
+ void showProgress();
+
+ void hideProgress();
+
void obtainQrCodeData(QrCodeBean userBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
new file mode 100644
index 0000000..4109e3c
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
@@ -0,0 +1,184 @@
+package com.casic.birmm.hxrq.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.ImageFormat;
+import android.hardware.Camera;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import androidx.annotation.NonNull;
+
+import com.casic.birmm.hxrq.R;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.utils.ImageHelper;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Stack;
+
+import butterknife.BindView;
+
+public class FacePreViewActivity extends BaseActivity implements Camera.PreviewCallback {
+
+ private static final int preViewWidth = 720;
+ private static final int preViewHeight = 1280;
+ @BindView(R.id.surfaceView)
+ SurfaceView surfaceView;
+ private SurfaceHolder mSurfaceHolder;
+ private Camera mCamera;
+ private ImageHelper imageHelper;
+ private Stack bitmapStack;
+ private boolean isCanLogin = true;
+
+ @Override
+ public int initLayoutView() {
+ return R.layout.activity_face;
+ }
+
+ @Override
+ protected void setupTopBarLayout() {
+
+ }
+
+ @Override
+ public void initData() {
+ imageHelper = new ImageHelper(this);
+ bitmapStack = new Stack<>();
+ }
+
+ @Override
+ public void initEvent() {
+ // 绑定SurfaceView,取得SurfaceHolder对象
+ mSurfaceHolder = surfaceView.getHolder();
+ mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(@NonNull SurfaceHolder holder) {
+ if (mCamera == null) {
+ //打开相机
+ openCamera();
+ }
+ try {
+ //预览画面
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ //开始预览
+ mCamera.startPreview();
+ }
+
+ @Override
+ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
+
+ }
+
+ @Override
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+ releaseCamera(); //释放相机资源
+ }
+ });
+ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置
+ }
+
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ camera.addCallbackBuffer(data);
+ Camera.Size size = camera.getParameters().getPreviewSize();//必须是相机支持的预览尺寸,否则颜色YUV空间会错位
+ Bitmap originBitmap = imageHelper.nv21ToBitmap(data, size.width, size.height);
+ //要使用Android内置的人脸识别,需要将Bitmap对象转为RGB_565格式,否则无法识别
+// Bitmap faceDetectorBitmap = originBitmap.copy(Bitmap.Config.RGB_565, true);
+// FaceDetector.Face[] faces = new FaceDetector.Face[1];
+// FaceDetector faceDetector = new FaceDetector(faceDetectorBitmap.getWidth(), faceDetectorBitmap.getHeight(), 1);
+// int faceSum = faceDetector.findFaces(faceDetectorBitmap, faces);
+// if (faceSum == 1) {
+ bitmapStack.push(originBitmap);
+ if (bitmapStack.size() >= 5) {//当栈里有5张bitmap之后才开始识别
+ if (isCanLogin) {
+ isCanLogin = false;
+ Bitmap bitmap = bitmapStack.pop();
+ Intent intent = new Intent();
+ intent.putExtra("imageToBase64", ImageHelper.imageToBase64(bitmap));
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ } else {
+ finish();
+ }
+ }
+// } else {
+// Log.d(TAG, "detectorFace: 未检测到人脸");
+// }
+ }
+
+ /**
+ * 打开相机
+ */
+ private void openCamera() {
+ try {
+ mCamera = Camera.open(1);
+ initParameters(mCamera); //初始化相机配置信息
+ mCamera.setPreviewCallback(this);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 初始化相机属性
+ */
+ private void initParameters(Camera camera) {
+ try {
+ Camera.Parameters mParameters = camera.getParameters();
+ mParameters.setPreviewFormat(ImageFormat.NV21); //设置预览图片的格式
+ //获取与指定宽高相等或最接近的尺寸
+ //设置预览尺寸
+ Camera.Size bestPreviewSize = obtainBestSize(preViewWidth, preViewHeight, mParameters.getSupportedPreviewSizes());
+ mParameters.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height);
+ //设置保存图片尺寸
+// Camera.Size bestPicSize = obtainBestSize(picWidth, picHeight, mParameters.getSupportedPictureSizes());
+// mParameters.setPictureSize(bestPicSize.width, bestPicSize.height);
+ //对焦模式
+ mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ camera.setDisplayOrientation(90);
+ camera.setParameters(mParameters);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 获取最合适的尺寸
+ */
+ private Camera.Size obtainBestSize(int targetWidth, int targetHeight, List sizeList) {
+ Camera.Size bestSize = null;
+ int targetRatio = targetHeight / targetWidth;//目标大小的宽高比
+ int minDiff = targetRatio;
+
+ for (Camera.Size size : sizeList) {
+ if (size.width == targetHeight && size.height == targetWidth) {
+ bestSize = size;
+ break;
+ }
+ int supportedRatio = (size.width / size.height);
+ if (Math.abs(supportedRatio - targetRatio) < minDiff) {
+ minDiff = Math.abs(supportedRatio - targetRatio);
+ bestSize = size;
+ }
+ }
+ return bestSize;
+ }
+
+ /**
+ * 释放相机资源
+ */
+ private void releaseCamera() {
+ if (mCamera != null) {
+ mCamera.stopPreview();
+ mCamera.setPreviewCallback(null);
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
index 98aef9d..30c26c8 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
@@ -8,14 +8,15 @@
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.casic.birmm.hxrq.R;
-import com.casic.birmm.hxrq.base.DoubleClickExitActivity;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -28,23 +29,16 @@
import com.casic.birmm.hxrq.mvp.view.IFaceLoginView;
import com.casic.birmm.hxrq.mvp.view.ILoginView;
import com.casic.birmm.hxrq.mvp.view.IQrCodeDataView;
-import com.casic.birmm.hxrq.utils.FileUtils;
-import com.casic.birmm.hxrq.utils.GlideLoadEngine;
+import com.casic.birmm.hxrq.utils.Constant;
import com.casic.birmm.hxrq.utils.RSAUtils;
import com.casic.birmm.hxrq.utils.SaveKeyValues;
-import com.casic.birmm.hxrq.utils.StringHelper;
import com.casic.birmm.hxrq.utils.TokenHelper;
import com.google.gson.Gson;
-import com.luck.picture.lib.PictureSelector;
-import com.luck.picture.lib.config.PictureConfig;
-import com.luck.picture.lib.config.PictureMimeType;
-import com.luck.picture.lib.entity.LocalMedia;
import com.qmuiteam.qmui.util.QMUIStatusBarHelper;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton;
-import java.io.File;
import java.security.PublicKey;
import butterknife.BindView;
@@ -53,15 +47,11 @@
import cn.bertsir.zbar.QrConfig;
import cn.bertsir.zbar.QrManager;
import cn.bertsir.zbar.view.ScanLineView;
-import top.zibin.luban.CompressionPredicate;
-import top.zibin.luban.Luban;
-import top.zibin.luban.OnCompressListener;
-public class LoginActivity extends DoubleClickExitActivity
- implements View.OnClickListener, IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
+public class LoginActivity extends BaseActivity implements View.OnClickListener,
+ IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
private static final String TAG = "LoginActivity";
-
@BindView(R.id.userNameView)
EditText userNameView;
@BindView(R.id.userPasswordView)
@@ -76,8 +66,8 @@
private LoginPresenterImpl loginPresenter;
private QrCodePresenterImpl qrCodePresenter;
private FaceLoginPresenterImpl faceLoginPresenter;
- private String userName;
- private String userPassword;
+ private boolean isPasswordLogin = false;
+ private String qrCode = "";
@Override
public int initLayoutView() {
@@ -86,20 +76,29 @@
@Override
protected void setupTopBarLayout() {
- //TODO 此页面无需实现
+ //设置状态栏黑色字体图标
+ QMUIStatusBarHelper.setStatusBarLightMode(this);
}
@Override
public void initData() {
- //设置状态栏黑色字体图标
- QMUIStatusBarHelper.setStatusBarLightMode(this);
-
String userName = (String) SaveKeyValues.getValue("userName", "");
String userPassword = (String) SaveKeyValues.getValue("userPassword", "");
+ userNameView.setText(userName);
+ userPasswordView.setText(userPassword);
if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) {
- userNameView.setText(userName);
- userPasswordView.setText(userPassword);
+ rememberPasswordView.setChecked(true);
+ } else {
+ rememberPasswordView.setChecked(false);
}
+ rememberPasswordView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (!isChecked) {
+ SaveKeyValues.removeKey("userPassword");
+ }
+ }
+ });
loadingDialog = new QMUITipDialog.Builder(this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
.setTipWord("登陆中,请稍后")
@@ -124,14 +123,9 @@
public void onClick(View v) {
switch (v.getId()) {
case R.id.loginButton:
- userName = userNameView.getText().toString();
- userPassword = userPasswordView.getText().toString();
- if (rememberPasswordView.isChecked()) {
- SaveKeyValues.putValue("userName", userName);
- SaveKeyValues.putValue("userPassword", userPassword);
- }
//密码登录前需要验证sid
authenticatePresenter.onReadyRetrofitRequest();
+ isPasswordLogin = true;
break;
case R.id.changeLoginModeView:
//首次登录不可用扫码,因为还未注册
@@ -169,50 +163,19 @@
}
private void captureFaceData() {
- //TODO 调相机,捕获人脸数据,并保存为文件得到路径
- PictureSelector.create(this)
- .openCamera(PictureMimeType.ofImage())
- .imageEngine(GlideLoadEngine.createGlideEngine())
- .maxSelectNum(1)
- .forResult(PictureConfig.REQUEST_CAMERA);
+ // 调相机,捕获人脸数据,并保存为文件得到路径
+ startActivityForResult(new Intent(this, FacePreViewActivity.class), Constant.FACE_DETECTOR_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
- if (requestCode == PictureConfig.REQUEST_CAMERA) {
- LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0);
- Luban.with(this)
- .load(localMedia.getRealPath())
- .ignoreBy(100)
- .setTargetDir(FileUtils.getFileDir("CompressImageFile"))
- .filter(new CompressionPredicate() {
- @Override
- public boolean apply(String path) {
- return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));
- }
- })
- .setCompressListener(new OnCompressListener() {
- @Override
- public void onStart() {
- // TODO 压缩开始前调用,可以在方法内启动 loading UI
- }
-
- @Override
- public void onSuccess(File file) {
- String imageToBase64 = StringHelper.imageToBase64(file);
-
- ImageBean imageBean = new ImageBean();
- imageBean.setImage(imageToBase64);
- faceLoginPresenter.onReadyRetrofitRequest(imageBean);
- }
-
- @Override
- public void onError(Throwable e) {
- // TODO 当压缩过程出现问题时调用
- }
- }).launch();
+ if (requestCode == Constant.FACE_DETECTOR_CODE) {
+ String imageToBase64 = data.getStringExtra("imageToBase64");
+ ImageBean imageBean = new ImageBean();
+ imageBean.setImage(imageToBase64);
+ faceLoginPresenter.onReadyRetrofitRequest(imageBean);
}
}
}
@@ -232,7 +195,7 @@
.setPlaySound(true)//是否扫描成功后bi~的声音
.setDingPath(R.raw.qrcode)//设置提示音(不设置为默认的Ding~)
.setIsOnlyCenter(true)//是否只识别框中内容(默认为全屏识别)
- .setTitleBackgroudColor(Color.parseColor("#262020"))//设置状态栏颜色
+ .setTitleBackgroudColor(R.color.black)//设置状态栏颜色
.setTitleTextColor(Color.WHITE)//设置Title文字颜色
.setScreenOrientation(QrConfig.SCREEN_PORTRAIT)//设置屏幕方式
.setScanLineStyle(ScanLineView.style_hybrid)//扫描线样式
@@ -241,8 +204,8 @@
QrManager.getInstance().init(qrConfig).startScan(this, new QrManager.OnScanResultCallback() {
@Override
public void onScanSuccess(final ScanResult result) {
-// Log.d(TAG, "扫码结果: " + result.content);
- qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), result.content);
+ qrCode = result.content;
+ authenticatePresenter.onReadyRetrofitRequest();//需要时时保持最新token,所以扫码登录之前需要获取最新token
}
});
}
@@ -254,9 +217,15 @@
@Override
public void authenticateResult(PublicKeyBean result) {
- Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
+// Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
if (result.isSuccess()) {
PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey());
+ String userName = userNameView.getText().toString();
+ String userPassword = userPasswordView.getText().toString();
+ if (rememberPasswordView.isChecked()) {
+ SaveKeyValues.putValue("userName", userName);
+ SaveKeyValues.putValue("userPassword", userPassword);
+ }
if (TextUtils.isEmpty(userName)) {
Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show();
return;
@@ -266,7 +235,6 @@
return;
}
String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey);
- Log.d(TAG, "authenticateResult: 验证成功,开始登录");
//登录并获取Token,POST请求
loginPresenter.onReadyRetrofitRequest(result.getData().getSid(), userName, dataByPublicKey);
} else {
@@ -283,11 +251,14 @@
String token = result.getData().getToken();
if (!TextUtils.isEmpty(token)) {
//获取用户信息
- Log.d(TAG, "obtainLoginResult: 获取Token成功");
TokenHelper.saveToken(token);
//验证成功登录
- startActivity(new Intent(this, MainActivity.class));
- finish();
+ if (isPasswordLogin) {
+ startActivity(new Intent(this, MainActivity.class));
+ finish();
+ } else {
+ qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), qrCode);
+ }
}
}
@@ -307,15 +278,17 @@
}
@Override
- public void obtainFaceLoginData(FaceLoginResultBean resultBean) {
-// Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
- if (resultBean.getCode() == 200) {
+ public void obtainFaceLoginData(FaceResultBean resultBean) {
+ Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
+ if (resultBean.isSuccess()) {
+ //{"code":200,"data":{"kaptcha":"","token":"9135bcb7-4f39-4b7a-a10e-555406ddb9e1"},"exceptionClazz":"","message":"登录成功","success":true}
TokenHelper.saveToken(resultBean.getData().getToken());
//验证成功登录
startActivity(new Intent(this, MainActivity.class));
finish();
} else {
- Toast.makeText(this, "无法解析人脸", Toast.LENGTH_SHORT).show();
+ //{"code":200,"data":"","exceptionClazz":"","message":"图片中没有人脸","success":false}
+ Toast.makeText(this, "人脸识别失败", Toast.LENGTH_SHORT).show();
}
}
@@ -336,5 +309,8 @@
if (qrCodePresenter != null) {
qrCodePresenter.disposeRetrofitRequest();
}
+ if (faceLoginPresenter != null) {
+ faceLoginPresenter.disposeRetrofitRequest();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
index e8e9b75..759a94d 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
@@ -9,4 +9,5 @@
Manifest.permission.WRITE_EXTERNAL_STORAGE};
public static final int PERMISSIONS_CODE = 999;
+ public static final int FACE_DETECTOR_CODE = 998;
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
new file mode 100644
index 0000000..b774ee9
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
@@ -0,0 +1,95 @@
+package com.casic.birmm.hxrq.utils;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.ImageFormat;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.YuvImage;
+import android.util.Base64;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class ImageHelper {
+
+ public ImageHelper(Context context) {
+
+ }
+
+ public Bitmap nv21ToBitmap(byte[] nv21, int width, int height) {
+ Bitmap bitmap = null;
+ try {
+ final YuvImage image = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ image.compressToJpeg(new Rect(0, 0, width, height), 80, outputStream);
+ final Bitmap bmp = BitmapFactory.decodeByteArray(outputStream.toByteArray(), 0, outputStream.size());
+ bitmap = rotateImageView(-90, bmp);
+ outputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return bitmap;
+ }
+
+ public Bitmap rotateImageView(int angle, Bitmap bitmap) {
+ //旋转图片 动作
+ Matrix matrix = new Matrix();
+ matrix.postRotate(angle);
+ // 创建新的图片
+ return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(File file) {
+ if (file == null) {
+ return null;
+ }
+ try {
+ FileInputStream fis = new FileInputStream(file);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] b = new byte[1024];
+ int n;
+ while ((n = fis.read(b)) != -1) {
+ bos.write(b, 0, n);
+ }
+ fis.close();
+ bos.close();
+
+ byte[] imgBytes = bos.toByteArray();
+ String result = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(Bitmap bitmap) {
+ if (bitmap == null) {
+ return null;
+ }
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);//压缩质量
+
+ outputStream.flush();
+ outputStream.close();
+
+ byte[] bitmapBytes = outputStream.toByteArray();
+ String result = Base64.encodeToString(bitmapBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (IOException e) {
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
index f4af6a5..e7772dd 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
@@ -3,33 +3,26 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
-import android.util.Log;
public class SaveKeyValues {
- private static final String TAG = "SaveKeyValues";
-
- @SuppressLint({"StaticFieldLeak"})
- private static Context context;
private static SharedPreferences sharedPreferences;
private static SharedPreferences.Editor editor;
- private static String fileName;
+ @SuppressLint("CommitPrefEdits")
public static void initSharedPreferences(Context mContext) {
- context = mContext.getApplicationContext();
- String packageName = context.getPackageName();
+ String packageName = mContext.getPackageName();
//获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms
String[] split = packageName.split("\\.");//先转义.之后才能分割
int length = split.length;
- fileName = split[length - 1];
- Log.d(TAG, fileName);
+ String fileName = split[length - 1];
+ sharedPreferences = mContext.getSharedPreferences(fileName, Context.MODE_PRIVATE);
+ editor = sharedPreferences.edit();
}
/**
* 存储
*/
public static void putValue(String key, Object object) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
- editor = sharedPreferences.edit();
if (object instanceof String) {
editor.putString(key, (String) object);
} else if (object instanceof Integer) {
@@ -50,7 +43,6 @@
* 获取保存的数据
*/
public static Object getValue(String key, Object defaultObject) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
if (defaultObject instanceof String) {
return sharedPreferences.getString(key, (String) defaultObject);
} else if (defaultObject instanceof Integer) {
@@ -86,7 +78,6 @@
* 查询某个key是否存在
*/
public static boolean containsKey(String key) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
return sharedPreferences.contains(key);
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java
deleted file mode 100644
index 0ebf16a..0000000
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.casic.birmm.hxrq.utils;
-
-import android.util.Base64;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-
-/**
- * @Author: Pengxh
- * @Time: 2021/4/9 15:12
- * @Email: 290677893@qq.com
- **/
-public class StringHelper {
- /**
- * 获取图片base64编码
- */
- public static String imageToBase64(File file) {
- if (file == null) {
- return null;
- }
- try {
- FileInputStream fis = new FileInputStream(file);
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- byte[] b = new byte[1024];
- int n;
- while ((n = fis.read(b)) != -1) {
- bos.write(b, 0, n);
- }
- fis.close();
- bos.close();
-
- byte[] imgBytes = bos.toByteArray();
- String s = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
- return s.replace("-", "+")
- .replace("_", "/");
- } catch (Exception e) {
- return null;
- }
- }
-}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
index 8fe5264..1de1ff4 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.utils.retrofit;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -49,6 +49,6 @@
*/
@Headers({"Content-Type: application/json"})
@POST("/cockpit/face/login")
- Observable getFaceLoginResult(
+ Observable getFaceLoginResult(
@Body ImageBean imageBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java
index ef4307e..d481055 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java
@@ -2,7 +2,7 @@
import android.util.Log;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -10,7 +10,6 @@
import com.casic.birmm.hxrq.utils.HttpConfig;
import org.jetbrains.annotations.NotNull;
-import org.json.JSONObject;
import java.util.concurrent.TimeUnit;
@@ -79,7 +78,7 @@
/**
* 人脸识别登录结果
*/
- public static Observable getFaceResult(String baseUrl, ImageBean imageBean) {
+ public static Observable getFaceResult(String baseUrl, ImageBean imageBean) {
Retrofit retrofit = createRetrofit(baseUrl);
RetrofitService service = retrofit.create(RetrofitService.class);
return service.getFaceLoginResult(imageBean);
diff --git a/app/src/main/res/drawable/bg_circle_image.xml b/app/src/main/res/drawable/bg_circle_image.xml
new file mode 100644
index 0000000..5b27ca4
--- /dev/null
+++ b/app/src/main/res/drawable/bg_circle_image.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
index c6d3e33..7e502f2 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
@@ -1,7 +1,11 @@
package com.casic.birmm.hxrq.mvp.view;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
public interface IFaceLoginView {
- void obtainFaceLoginData(FaceLoginResultBean resultBean);
+ void showProgress();
+
+ void hideProgress();
+
+ void obtainFaceLoginData(FaceResultBean resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
index c9783cd..fe666b1 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
@@ -3,6 +3,8 @@
import com.casic.birmm.hxrq.bean.LoginResultBean;
public interface ILoginView {
+ void showProgress();
+
void hideProgress();
void obtainLoginResult(LoginResultBean resultBean);
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
index 4e8821e..4003e26 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
@@ -3,5 +3,9 @@
import com.casic.birmm.hxrq.bean.QrCodeBean;
public interface IQrCodeDataView {
+ void showProgress();
+
+ void hideProgress();
+
void obtainQrCodeData(QrCodeBean userBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
new file mode 100644
index 0000000..4109e3c
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
@@ -0,0 +1,184 @@
+package com.casic.birmm.hxrq.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.ImageFormat;
+import android.hardware.Camera;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import androidx.annotation.NonNull;
+
+import com.casic.birmm.hxrq.R;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.utils.ImageHelper;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Stack;
+
+import butterknife.BindView;
+
+public class FacePreViewActivity extends BaseActivity implements Camera.PreviewCallback {
+
+ private static final int preViewWidth = 720;
+ private static final int preViewHeight = 1280;
+ @BindView(R.id.surfaceView)
+ SurfaceView surfaceView;
+ private SurfaceHolder mSurfaceHolder;
+ private Camera mCamera;
+ private ImageHelper imageHelper;
+ private Stack bitmapStack;
+ private boolean isCanLogin = true;
+
+ @Override
+ public int initLayoutView() {
+ return R.layout.activity_face;
+ }
+
+ @Override
+ protected void setupTopBarLayout() {
+
+ }
+
+ @Override
+ public void initData() {
+ imageHelper = new ImageHelper(this);
+ bitmapStack = new Stack<>();
+ }
+
+ @Override
+ public void initEvent() {
+ // 绑定SurfaceView,取得SurfaceHolder对象
+ mSurfaceHolder = surfaceView.getHolder();
+ mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(@NonNull SurfaceHolder holder) {
+ if (mCamera == null) {
+ //打开相机
+ openCamera();
+ }
+ try {
+ //预览画面
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ //开始预览
+ mCamera.startPreview();
+ }
+
+ @Override
+ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
+
+ }
+
+ @Override
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+ releaseCamera(); //释放相机资源
+ }
+ });
+ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置
+ }
+
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ camera.addCallbackBuffer(data);
+ Camera.Size size = camera.getParameters().getPreviewSize();//必须是相机支持的预览尺寸,否则颜色YUV空间会错位
+ Bitmap originBitmap = imageHelper.nv21ToBitmap(data, size.width, size.height);
+ //要使用Android内置的人脸识别,需要将Bitmap对象转为RGB_565格式,否则无法识别
+// Bitmap faceDetectorBitmap = originBitmap.copy(Bitmap.Config.RGB_565, true);
+// FaceDetector.Face[] faces = new FaceDetector.Face[1];
+// FaceDetector faceDetector = new FaceDetector(faceDetectorBitmap.getWidth(), faceDetectorBitmap.getHeight(), 1);
+// int faceSum = faceDetector.findFaces(faceDetectorBitmap, faces);
+// if (faceSum == 1) {
+ bitmapStack.push(originBitmap);
+ if (bitmapStack.size() >= 5) {//当栈里有5张bitmap之后才开始识别
+ if (isCanLogin) {
+ isCanLogin = false;
+ Bitmap bitmap = bitmapStack.pop();
+ Intent intent = new Intent();
+ intent.putExtra("imageToBase64", ImageHelper.imageToBase64(bitmap));
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ } else {
+ finish();
+ }
+ }
+// } else {
+// Log.d(TAG, "detectorFace: 未检测到人脸");
+// }
+ }
+
+ /**
+ * 打开相机
+ */
+ private void openCamera() {
+ try {
+ mCamera = Camera.open(1);
+ initParameters(mCamera); //初始化相机配置信息
+ mCamera.setPreviewCallback(this);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 初始化相机属性
+ */
+ private void initParameters(Camera camera) {
+ try {
+ Camera.Parameters mParameters = camera.getParameters();
+ mParameters.setPreviewFormat(ImageFormat.NV21); //设置预览图片的格式
+ //获取与指定宽高相等或最接近的尺寸
+ //设置预览尺寸
+ Camera.Size bestPreviewSize = obtainBestSize(preViewWidth, preViewHeight, mParameters.getSupportedPreviewSizes());
+ mParameters.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height);
+ //设置保存图片尺寸
+// Camera.Size bestPicSize = obtainBestSize(picWidth, picHeight, mParameters.getSupportedPictureSizes());
+// mParameters.setPictureSize(bestPicSize.width, bestPicSize.height);
+ //对焦模式
+ mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ camera.setDisplayOrientation(90);
+ camera.setParameters(mParameters);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 获取最合适的尺寸
+ */
+ private Camera.Size obtainBestSize(int targetWidth, int targetHeight, List sizeList) {
+ Camera.Size bestSize = null;
+ int targetRatio = targetHeight / targetWidth;//目标大小的宽高比
+ int minDiff = targetRatio;
+
+ for (Camera.Size size : sizeList) {
+ if (size.width == targetHeight && size.height == targetWidth) {
+ bestSize = size;
+ break;
+ }
+ int supportedRatio = (size.width / size.height);
+ if (Math.abs(supportedRatio - targetRatio) < minDiff) {
+ minDiff = Math.abs(supportedRatio - targetRatio);
+ bestSize = size;
+ }
+ }
+ return bestSize;
+ }
+
+ /**
+ * 释放相机资源
+ */
+ private void releaseCamera() {
+ if (mCamera != null) {
+ mCamera.stopPreview();
+ mCamera.setPreviewCallback(null);
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
index 98aef9d..30c26c8 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
@@ -8,14 +8,15 @@
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.casic.birmm.hxrq.R;
-import com.casic.birmm.hxrq.base.DoubleClickExitActivity;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -28,23 +29,16 @@
import com.casic.birmm.hxrq.mvp.view.IFaceLoginView;
import com.casic.birmm.hxrq.mvp.view.ILoginView;
import com.casic.birmm.hxrq.mvp.view.IQrCodeDataView;
-import com.casic.birmm.hxrq.utils.FileUtils;
-import com.casic.birmm.hxrq.utils.GlideLoadEngine;
+import com.casic.birmm.hxrq.utils.Constant;
import com.casic.birmm.hxrq.utils.RSAUtils;
import com.casic.birmm.hxrq.utils.SaveKeyValues;
-import com.casic.birmm.hxrq.utils.StringHelper;
import com.casic.birmm.hxrq.utils.TokenHelper;
import com.google.gson.Gson;
-import com.luck.picture.lib.PictureSelector;
-import com.luck.picture.lib.config.PictureConfig;
-import com.luck.picture.lib.config.PictureMimeType;
-import com.luck.picture.lib.entity.LocalMedia;
import com.qmuiteam.qmui.util.QMUIStatusBarHelper;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton;
-import java.io.File;
import java.security.PublicKey;
import butterknife.BindView;
@@ -53,15 +47,11 @@
import cn.bertsir.zbar.QrConfig;
import cn.bertsir.zbar.QrManager;
import cn.bertsir.zbar.view.ScanLineView;
-import top.zibin.luban.CompressionPredicate;
-import top.zibin.luban.Luban;
-import top.zibin.luban.OnCompressListener;
-public class LoginActivity extends DoubleClickExitActivity
- implements View.OnClickListener, IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
+public class LoginActivity extends BaseActivity implements View.OnClickListener,
+ IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
private static final String TAG = "LoginActivity";
-
@BindView(R.id.userNameView)
EditText userNameView;
@BindView(R.id.userPasswordView)
@@ -76,8 +66,8 @@
private LoginPresenterImpl loginPresenter;
private QrCodePresenterImpl qrCodePresenter;
private FaceLoginPresenterImpl faceLoginPresenter;
- private String userName;
- private String userPassword;
+ private boolean isPasswordLogin = false;
+ private String qrCode = "";
@Override
public int initLayoutView() {
@@ -86,20 +76,29 @@
@Override
protected void setupTopBarLayout() {
- //TODO 此页面无需实现
+ //设置状态栏黑色字体图标
+ QMUIStatusBarHelper.setStatusBarLightMode(this);
}
@Override
public void initData() {
- //设置状态栏黑色字体图标
- QMUIStatusBarHelper.setStatusBarLightMode(this);
-
String userName = (String) SaveKeyValues.getValue("userName", "");
String userPassword = (String) SaveKeyValues.getValue("userPassword", "");
+ userNameView.setText(userName);
+ userPasswordView.setText(userPassword);
if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) {
- userNameView.setText(userName);
- userPasswordView.setText(userPassword);
+ rememberPasswordView.setChecked(true);
+ } else {
+ rememberPasswordView.setChecked(false);
}
+ rememberPasswordView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (!isChecked) {
+ SaveKeyValues.removeKey("userPassword");
+ }
+ }
+ });
loadingDialog = new QMUITipDialog.Builder(this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
.setTipWord("登陆中,请稍后")
@@ -124,14 +123,9 @@
public void onClick(View v) {
switch (v.getId()) {
case R.id.loginButton:
- userName = userNameView.getText().toString();
- userPassword = userPasswordView.getText().toString();
- if (rememberPasswordView.isChecked()) {
- SaveKeyValues.putValue("userName", userName);
- SaveKeyValues.putValue("userPassword", userPassword);
- }
//密码登录前需要验证sid
authenticatePresenter.onReadyRetrofitRequest();
+ isPasswordLogin = true;
break;
case R.id.changeLoginModeView:
//首次登录不可用扫码,因为还未注册
@@ -169,50 +163,19 @@
}
private void captureFaceData() {
- //TODO 调相机,捕获人脸数据,并保存为文件得到路径
- PictureSelector.create(this)
- .openCamera(PictureMimeType.ofImage())
- .imageEngine(GlideLoadEngine.createGlideEngine())
- .maxSelectNum(1)
- .forResult(PictureConfig.REQUEST_CAMERA);
+ // 调相机,捕获人脸数据,并保存为文件得到路径
+ startActivityForResult(new Intent(this, FacePreViewActivity.class), Constant.FACE_DETECTOR_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
- if (requestCode == PictureConfig.REQUEST_CAMERA) {
- LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0);
- Luban.with(this)
- .load(localMedia.getRealPath())
- .ignoreBy(100)
- .setTargetDir(FileUtils.getFileDir("CompressImageFile"))
- .filter(new CompressionPredicate() {
- @Override
- public boolean apply(String path) {
- return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));
- }
- })
- .setCompressListener(new OnCompressListener() {
- @Override
- public void onStart() {
- // TODO 压缩开始前调用,可以在方法内启动 loading UI
- }
-
- @Override
- public void onSuccess(File file) {
- String imageToBase64 = StringHelper.imageToBase64(file);
-
- ImageBean imageBean = new ImageBean();
- imageBean.setImage(imageToBase64);
- faceLoginPresenter.onReadyRetrofitRequest(imageBean);
- }
-
- @Override
- public void onError(Throwable e) {
- // TODO 当压缩过程出现问题时调用
- }
- }).launch();
+ if (requestCode == Constant.FACE_DETECTOR_CODE) {
+ String imageToBase64 = data.getStringExtra("imageToBase64");
+ ImageBean imageBean = new ImageBean();
+ imageBean.setImage(imageToBase64);
+ faceLoginPresenter.onReadyRetrofitRequest(imageBean);
}
}
}
@@ -232,7 +195,7 @@
.setPlaySound(true)//是否扫描成功后bi~的声音
.setDingPath(R.raw.qrcode)//设置提示音(不设置为默认的Ding~)
.setIsOnlyCenter(true)//是否只识别框中内容(默认为全屏识别)
- .setTitleBackgroudColor(Color.parseColor("#262020"))//设置状态栏颜色
+ .setTitleBackgroudColor(R.color.black)//设置状态栏颜色
.setTitleTextColor(Color.WHITE)//设置Title文字颜色
.setScreenOrientation(QrConfig.SCREEN_PORTRAIT)//设置屏幕方式
.setScanLineStyle(ScanLineView.style_hybrid)//扫描线样式
@@ -241,8 +204,8 @@
QrManager.getInstance().init(qrConfig).startScan(this, new QrManager.OnScanResultCallback() {
@Override
public void onScanSuccess(final ScanResult result) {
-// Log.d(TAG, "扫码结果: " + result.content);
- qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), result.content);
+ qrCode = result.content;
+ authenticatePresenter.onReadyRetrofitRequest();//需要时时保持最新token,所以扫码登录之前需要获取最新token
}
});
}
@@ -254,9 +217,15 @@
@Override
public void authenticateResult(PublicKeyBean result) {
- Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
+// Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
if (result.isSuccess()) {
PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey());
+ String userName = userNameView.getText().toString();
+ String userPassword = userPasswordView.getText().toString();
+ if (rememberPasswordView.isChecked()) {
+ SaveKeyValues.putValue("userName", userName);
+ SaveKeyValues.putValue("userPassword", userPassword);
+ }
if (TextUtils.isEmpty(userName)) {
Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show();
return;
@@ -266,7 +235,6 @@
return;
}
String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey);
- Log.d(TAG, "authenticateResult: 验证成功,开始登录");
//登录并获取Token,POST请求
loginPresenter.onReadyRetrofitRequest(result.getData().getSid(), userName, dataByPublicKey);
} else {
@@ -283,11 +251,14 @@
String token = result.getData().getToken();
if (!TextUtils.isEmpty(token)) {
//获取用户信息
- Log.d(TAG, "obtainLoginResult: 获取Token成功");
TokenHelper.saveToken(token);
//验证成功登录
- startActivity(new Intent(this, MainActivity.class));
- finish();
+ if (isPasswordLogin) {
+ startActivity(new Intent(this, MainActivity.class));
+ finish();
+ } else {
+ qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), qrCode);
+ }
}
}
@@ -307,15 +278,17 @@
}
@Override
- public void obtainFaceLoginData(FaceLoginResultBean resultBean) {
-// Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
- if (resultBean.getCode() == 200) {
+ public void obtainFaceLoginData(FaceResultBean resultBean) {
+ Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
+ if (resultBean.isSuccess()) {
+ //{"code":200,"data":{"kaptcha":"","token":"9135bcb7-4f39-4b7a-a10e-555406ddb9e1"},"exceptionClazz":"","message":"登录成功","success":true}
TokenHelper.saveToken(resultBean.getData().getToken());
//验证成功登录
startActivity(new Intent(this, MainActivity.class));
finish();
} else {
- Toast.makeText(this, "无法解析人脸", Toast.LENGTH_SHORT).show();
+ //{"code":200,"data":"","exceptionClazz":"","message":"图片中没有人脸","success":false}
+ Toast.makeText(this, "人脸识别失败", Toast.LENGTH_SHORT).show();
}
}
@@ -336,5 +309,8 @@
if (qrCodePresenter != null) {
qrCodePresenter.disposeRetrofitRequest();
}
+ if (faceLoginPresenter != null) {
+ faceLoginPresenter.disposeRetrofitRequest();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
index e8e9b75..759a94d 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
@@ -9,4 +9,5 @@
Manifest.permission.WRITE_EXTERNAL_STORAGE};
public static final int PERMISSIONS_CODE = 999;
+ public static final int FACE_DETECTOR_CODE = 998;
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
new file mode 100644
index 0000000..b774ee9
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
@@ -0,0 +1,95 @@
+package com.casic.birmm.hxrq.utils;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.ImageFormat;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.YuvImage;
+import android.util.Base64;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class ImageHelper {
+
+ public ImageHelper(Context context) {
+
+ }
+
+ public Bitmap nv21ToBitmap(byte[] nv21, int width, int height) {
+ Bitmap bitmap = null;
+ try {
+ final YuvImage image = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ image.compressToJpeg(new Rect(0, 0, width, height), 80, outputStream);
+ final Bitmap bmp = BitmapFactory.decodeByteArray(outputStream.toByteArray(), 0, outputStream.size());
+ bitmap = rotateImageView(-90, bmp);
+ outputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return bitmap;
+ }
+
+ public Bitmap rotateImageView(int angle, Bitmap bitmap) {
+ //旋转图片 动作
+ Matrix matrix = new Matrix();
+ matrix.postRotate(angle);
+ // 创建新的图片
+ return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(File file) {
+ if (file == null) {
+ return null;
+ }
+ try {
+ FileInputStream fis = new FileInputStream(file);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] b = new byte[1024];
+ int n;
+ while ((n = fis.read(b)) != -1) {
+ bos.write(b, 0, n);
+ }
+ fis.close();
+ bos.close();
+
+ byte[] imgBytes = bos.toByteArray();
+ String result = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(Bitmap bitmap) {
+ if (bitmap == null) {
+ return null;
+ }
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);//压缩质量
+
+ outputStream.flush();
+ outputStream.close();
+
+ byte[] bitmapBytes = outputStream.toByteArray();
+ String result = Base64.encodeToString(bitmapBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (IOException e) {
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
index f4af6a5..e7772dd 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
@@ -3,33 +3,26 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
-import android.util.Log;
public class SaveKeyValues {
- private static final String TAG = "SaveKeyValues";
-
- @SuppressLint({"StaticFieldLeak"})
- private static Context context;
private static SharedPreferences sharedPreferences;
private static SharedPreferences.Editor editor;
- private static String fileName;
+ @SuppressLint("CommitPrefEdits")
public static void initSharedPreferences(Context mContext) {
- context = mContext.getApplicationContext();
- String packageName = context.getPackageName();
+ String packageName = mContext.getPackageName();
//获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms
String[] split = packageName.split("\\.");//先转义.之后才能分割
int length = split.length;
- fileName = split[length - 1];
- Log.d(TAG, fileName);
+ String fileName = split[length - 1];
+ sharedPreferences = mContext.getSharedPreferences(fileName, Context.MODE_PRIVATE);
+ editor = sharedPreferences.edit();
}
/**
* 存储
*/
public static void putValue(String key, Object object) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
- editor = sharedPreferences.edit();
if (object instanceof String) {
editor.putString(key, (String) object);
} else if (object instanceof Integer) {
@@ -50,7 +43,6 @@
* 获取保存的数据
*/
public static Object getValue(String key, Object defaultObject) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
if (defaultObject instanceof String) {
return sharedPreferences.getString(key, (String) defaultObject);
} else if (defaultObject instanceof Integer) {
@@ -86,7 +78,6 @@
* 查询某个key是否存在
*/
public static boolean containsKey(String key) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
return sharedPreferences.contains(key);
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java
deleted file mode 100644
index 0ebf16a..0000000
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.casic.birmm.hxrq.utils;
-
-import android.util.Base64;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-
-/**
- * @Author: Pengxh
- * @Time: 2021/4/9 15:12
- * @Email: 290677893@qq.com
- **/
-public class StringHelper {
- /**
- * 获取图片base64编码
- */
- public static String imageToBase64(File file) {
- if (file == null) {
- return null;
- }
- try {
- FileInputStream fis = new FileInputStream(file);
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- byte[] b = new byte[1024];
- int n;
- while ((n = fis.read(b)) != -1) {
- bos.write(b, 0, n);
- }
- fis.close();
- bos.close();
-
- byte[] imgBytes = bos.toByteArray();
- String s = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
- return s.replace("-", "+")
- .replace("_", "/");
- } catch (Exception e) {
- return null;
- }
- }
-}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
index 8fe5264..1de1ff4 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.utils.retrofit;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -49,6 +49,6 @@
*/
@Headers({"Content-Type: application/json"})
@POST("/cockpit/face/login")
- Observable getFaceLoginResult(
+ Observable getFaceLoginResult(
@Body ImageBean imageBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java
index ef4307e..d481055 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java
@@ -2,7 +2,7 @@
import android.util.Log;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -10,7 +10,6 @@
import com.casic.birmm.hxrq.utils.HttpConfig;
import org.jetbrains.annotations.NotNull;
-import org.json.JSONObject;
import java.util.concurrent.TimeUnit;
@@ -79,7 +78,7 @@
/**
* 人脸识别登录结果
*/
- public static Observable getFaceResult(String baseUrl, ImageBean imageBean) {
+ public static Observable getFaceResult(String baseUrl, ImageBean imageBean) {
Retrofit retrofit = createRetrofit(baseUrl);
RetrofitService service = retrofit.create(RetrofitService.class);
return service.getFaceLoginResult(imageBean);
diff --git a/app/src/main/res/drawable/bg_circle_image.xml b/app/src/main/res/drawable/bg_circle_image.xml
new file mode 100644
index 0000000..5b27ca4
--- /dev/null
+++ b/app/src/main/res/drawable/bg_circle_image.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_face.xml b/app/src/main/res/layout/activity_face.xml
new file mode 100644
index 0000000..0d2e4e0
--- /dev/null
+++ b/app/src/main/res/layout/activity_face.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
index c6d3e33..7e502f2 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
@@ -1,7 +1,11 @@
package com.casic.birmm.hxrq.mvp.view;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
public interface IFaceLoginView {
- void obtainFaceLoginData(FaceLoginResultBean resultBean);
+ void showProgress();
+
+ void hideProgress();
+
+ void obtainFaceLoginData(FaceResultBean resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
index c9783cd..fe666b1 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
@@ -3,6 +3,8 @@
import com.casic.birmm.hxrq.bean.LoginResultBean;
public interface ILoginView {
+ void showProgress();
+
void hideProgress();
void obtainLoginResult(LoginResultBean resultBean);
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
index 4e8821e..4003e26 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
@@ -3,5 +3,9 @@
import com.casic.birmm.hxrq.bean.QrCodeBean;
public interface IQrCodeDataView {
+ void showProgress();
+
+ void hideProgress();
+
void obtainQrCodeData(QrCodeBean userBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
new file mode 100644
index 0000000..4109e3c
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
@@ -0,0 +1,184 @@
+package com.casic.birmm.hxrq.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.ImageFormat;
+import android.hardware.Camera;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import androidx.annotation.NonNull;
+
+import com.casic.birmm.hxrq.R;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.utils.ImageHelper;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Stack;
+
+import butterknife.BindView;
+
+public class FacePreViewActivity extends BaseActivity implements Camera.PreviewCallback {
+
+ private static final int preViewWidth = 720;
+ private static final int preViewHeight = 1280;
+ @BindView(R.id.surfaceView)
+ SurfaceView surfaceView;
+ private SurfaceHolder mSurfaceHolder;
+ private Camera mCamera;
+ private ImageHelper imageHelper;
+ private Stack bitmapStack;
+ private boolean isCanLogin = true;
+
+ @Override
+ public int initLayoutView() {
+ return R.layout.activity_face;
+ }
+
+ @Override
+ protected void setupTopBarLayout() {
+
+ }
+
+ @Override
+ public void initData() {
+ imageHelper = new ImageHelper(this);
+ bitmapStack = new Stack<>();
+ }
+
+ @Override
+ public void initEvent() {
+ // 绑定SurfaceView,取得SurfaceHolder对象
+ mSurfaceHolder = surfaceView.getHolder();
+ mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(@NonNull SurfaceHolder holder) {
+ if (mCamera == null) {
+ //打开相机
+ openCamera();
+ }
+ try {
+ //预览画面
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ //开始预览
+ mCamera.startPreview();
+ }
+
+ @Override
+ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
+
+ }
+
+ @Override
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+ releaseCamera(); //释放相机资源
+ }
+ });
+ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置
+ }
+
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ camera.addCallbackBuffer(data);
+ Camera.Size size = camera.getParameters().getPreviewSize();//必须是相机支持的预览尺寸,否则颜色YUV空间会错位
+ Bitmap originBitmap = imageHelper.nv21ToBitmap(data, size.width, size.height);
+ //要使用Android内置的人脸识别,需要将Bitmap对象转为RGB_565格式,否则无法识别
+// Bitmap faceDetectorBitmap = originBitmap.copy(Bitmap.Config.RGB_565, true);
+// FaceDetector.Face[] faces = new FaceDetector.Face[1];
+// FaceDetector faceDetector = new FaceDetector(faceDetectorBitmap.getWidth(), faceDetectorBitmap.getHeight(), 1);
+// int faceSum = faceDetector.findFaces(faceDetectorBitmap, faces);
+// if (faceSum == 1) {
+ bitmapStack.push(originBitmap);
+ if (bitmapStack.size() >= 5) {//当栈里有5张bitmap之后才开始识别
+ if (isCanLogin) {
+ isCanLogin = false;
+ Bitmap bitmap = bitmapStack.pop();
+ Intent intent = new Intent();
+ intent.putExtra("imageToBase64", ImageHelper.imageToBase64(bitmap));
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ } else {
+ finish();
+ }
+ }
+// } else {
+// Log.d(TAG, "detectorFace: 未检测到人脸");
+// }
+ }
+
+ /**
+ * 打开相机
+ */
+ private void openCamera() {
+ try {
+ mCamera = Camera.open(1);
+ initParameters(mCamera); //初始化相机配置信息
+ mCamera.setPreviewCallback(this);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 初始化相机属性
+ */
+ private void initParameters(Camera camera) {
+ try {
+ Camera.Parameters mParameters = camera.getParameters();
+ mParameters.setPreviewFormat(ImageFormat.NV21); //设置预览图片的格式
+ //获取与指定宽高相等或最接近的尺寸
+ //设置预览尺寸
+ Camera.Size bestPreviewSize = obtainBestSize(preViewWidth, preViewHeight, mParameters.getSupportedPreviewSizes());
+ mParameters.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height);
+ //设置保存图片尺寸
+// Camera.Size bestPicSize = obtainBestSize(picWidth, picHeight, mParameters.getSupportedPictureSizes());
+// mParameters.setPictureSize(bestPicSize.width, bestPicSize.height);
+ //对焦模式
+ mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ camera.setDisplayOrientation(90);
+ camera.setParameters(mParameters);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 获取最合适的尺寸
+ */
+ private Camera.Size obtainBestSize(int targetWidth, int targetHeight, List sizeList) {
+ Camera.Size bestSize = null;
+ int targetRatio = targetHeight / targetWidth;//目标大小的宽高比
+ int minDiff = targetRatio;
+
+ for (Camera.Size size : sizeList) {
+ if (size.width == targetHeight && size.height == targetWidth) {
+ bestSize = size;
+ break;
+ }
+ int supportedRatio = (size.width / size.height);
+ if (Math.abs(supportedRatio - targetRatio) < minDiff) {
+ minDiff = Math.abs(supportedRatio - targetRatio);
+ bestSize = size;
+ }
+ }
+ return bestSize;
+ }
+
+ /**
+ * 释放相机资源
+ */
+ private void releaseCamera() {
+ if (mCamera != null) {
+ mCamera.stopPreview();
+ mCamera.setPreviewCallback(null);
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
index 98aef9d..30c26c8 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
@@ -8,14 +8,15 @@
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.casic.birmm.hxrq.R;
-import com.casic.birmm.hxrq.base.DoubleClickExitActivity;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -28,23 +29,16 @@
import com.casic.birmm.hxrq.mvp.view.IFaceLoginView;
import com.casic.birmm.hxrq.mvp.view.ILoginView;
import com.casic.birmm.hxrq.mvp.view.IQrCodeDataView;
-import com.casic.birmm.hxrq.utils.FileUtils;
-import com.casic.birmm.hxrq.utils.GlideLoadEngine;
+import com.casic.birmm.hxrq.utils.Constant;
import com.casic.birmm.hxrq.utils.RSAUtils;
import com.casic.birmm.hxrq.utils.SaveKeyValues;
-import com.casic.birmm.hxrq.utils.StringHelper;
import com.casic.birmm.hxrq.utils.TokenHelper;
import com.google.gson.Gson;
-import com.luck.picture.lib.PictureSelector;
-import com.luck.picture.lib.config.PictureConfig;
-import com.luck.picture.lib.config.PictureMimeType;
-import com.luck.picture.lib.entity.LocalMedia;
import com.qmuiteam.qmui.util.QMUIStatusBarHelper;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton;
-import java.io.File;
import java.security.PublicKey;
import butterknife.BindView;
@@ -53,15 +47,11 @@
import cn.bertsir.zbar.QrConfig;
import cn.bertsir.zbar.QrManager;
import cn.bertsir.zbar.view.ScanLineView;
-import top.zibin.luban.CompressionPredicate;
-import top.zibin.luban.Luban;
-import top.zibin.luban.OnCompressListener;
-public class LoginActivity extends DoubleClickExitActivity
- implements View.OnClickListener, IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
+public class LoginActivity extends BaseActivity implements View.OnClickListener,
+ IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
private static final String TAG = "LoginActivity";
-
@BindView(R.id.userNameView)
EditText userNameView;
@BindView(R.id.userPasswordView)
@@ -76,8 +66,8 @@
private LoginPresenterImpl loginPresenter;
private QrCodePresenterImpl qrCodePresenter;
private FaceLoginPresenterImpl faceLoginPresenter;
- private String userName;
- private String userPassword;
+ private boolean isPasswordLogin = false;
+ private String qrCode = "";
@Override
public int initLayoutView() {
@@ -86,20 +76,29 @@
@Override
protected void setupTopBarLayout() {
- //TODO 此页面无需实现
+ //设置状态栏黑色字体图标
+ QMUIStatusBarHelper.setStatusBarLightMode(this);
}
@Override
public void initData() {
- //设置状态栏黑色字体图标
- QMUIStatusBarHelper.setStatusBarLightMode(this);
-
String userName = (String) SaveKeyValues.getValue("userName", "");
String userPassword = (String) SaveKeyValues.getValue("userPassword", "");
+ userNameView.setText(userName);
+ userPasswordView.setText(userPassword);
if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) {
- userNameView.setText(userName);
- userPasswordView.setText(userPassword);
+ rememberPasswordView.setChecked(true);
+ } else {
+ rememberPasswordView.setChecked(false);
}
+ rememberPasswordView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (!isChecked) {
+ SaveKeyValues.removeKey("userPassword");
+ }
+ }
+ });
loadingDialog = new QMUITipDialog.Builder(this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
.setTipWord("登陆中,请稍后")
@@ -124,14 +123,9 @@
public void onClick(View v) {
switch (v.getId()) {
case R.id.loginButton:
- userName = userNameView.getText().toString();
- userPassword = userPasswordView.getText().toString();
- if (rememberPasswordView.isChecked()) {
- SaveKeyValues.putValue("userName", userName);
- SaveKeyValues.putValue("userPassword", userPassword);
- }
//密码登录前需要验证sid
authenticatePresenter.onReadyRetrofitRequest();
+ isPasswordLogin = true;
break;
case R.id.changeLoginModeView:
//首次登录不可用扫码,因为还未注册
@@ -169,50 +163,19 @@
}
private void captureFaceData() {
- //TODO 调相机,捕获人脸数据,并保存为文件得到路径
- PictureSelector.create(this)
- .openCamera(PictureMimeType.ofImage())
- .imageEngine(GlideLoadEngine.createGlideEngine())
- .maxSelectNum(1)
- .forResult(PictureConfig.REQUEST_CAMERA);
+ // 调相机,捕获人脸数据,并保存为文件得到路径
+ startActivityForResult(new Intent(this, FacePreViewActivity.class), Constant.FACE_DETECTOR_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
- if (requestCode == PictureConfig.REQUEST_CAMERA) {
- LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0);
- Luban.with(this)
- .load(localMedia.getRealPath())
- .ignoreBy(100)
- .setTargetDir(FileUtils.getFileDir("CompressImageFile"))
- .filter(new CompressionPredicate() {
- @Override
- public boolean apply(String path) {
- return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));
- }
- })
- .setCompressListener(new OnCompressListener() {
- @Override
- public void onStart() {
- // TODO 压缩开始前调用,可以在方法内启动 loading UI
- }
-
- @Override
- public void onSuccess(File file) {
- String imageToBase64 = StringHelper.imageToBase64(file);
-
- ImageBean imageBean = new ImageBean();
- imageBean.setImage(imageToBase64);
- faceLoginPresenter.onReadyRetrofitRequest(imageBean);
- }
-
- @Override
- public void onError(Throwable e) {
- // TODO 当压缩过程出现问题时调用
- }
- }).launch();
+ if (requestCode == Constant.FACE_DETECTOR_CODE) {
+ String imageToBase64 = data.getStringExtra("imageToBase64");
+ ImageBean imageBean = new ImageBean();
+ imageBean.setImage(imageToBase64);
+ faceLoginPresenter.onReadyRetrofitRequest(imageBean);
}
}
}
@@ -232,7 +195,7 @@
.setPlaySound(true)//是否扫描成功后bi~的声音
.setDingPath(R.raw.qrcode)//设置提示音(不设置为默认的Ding~)
.setIsOnlyCenter(true)//是否只识别框中内容(默认为全屏识别)
- .setTitleBackgroudColor(Color.parseColor("#262020"))//设置状态栏颜色
+ .setTitleBackgroudColor(R.color.black)//设置状态栏颜色
.setTitleTextColor(Color.WHITE)//设置Title文字颜色
.setScreenOrientation(QrConfig.SCREEN_PORTRAIT)//设置屏幕方式
.setScanLineStyle(ScanLineView.style_hybrid)//扫描线样式
@@ -241,8 +204,8 @@
QrManager.getInstance().init(qrConfig).startScan(this, new QrManager.OnScanResultCallback() {
@Override
public void onScanSuccess(final ScanResult result) {
-// Log.d(TAG, "扫码结果: " + result.content);
- qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), result.content);
+ qrCode = result.content;
+ authenticatePresenter.onReadyRetrofitRequest();//需要时时保持最新token,所以扫码登录之前需要获取最新token
}
});
}
@@ -254,9 +217,15 @@
@Override
public void authenticateResult(PublicKeyBean result) {
- Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
+// Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
if (result.isSuccess()) {
PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey());
+ String userName = userNameView.getText().toString();
+ String userPassword = userPasswordView.getText().toString();
+ if (rememberPasswordView.isChecked()) {
+ SaveKeyValues.putValue("userName", userName);
+ SaveKeyValues.putValue("userPassword", userPassword);
+ }
if (TextUtils.isEmpty(userName)) {
Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show();
return;
@@ -266,7 +235,6 @@
return;
}
String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey);
- Log.d(TAG, "authenticateResult: 验证成功,开始登录");
//登录并获取Token,POST请求
loginPresenter.onReadyRetrofitRequest(result.getData().getSid(), userName, dataByPublicKey);
} else {
@@ -283,11 +251,14 @@
String token = result.getData().getToken();
if (!TextUtils.isEmpty(token)) {
//获取用户信息
- Log.d(TAG, "obtainLoginResult: 获取Token成功");
TokenHelper.saveToken(token);
//验证成功登录
- startActivity(new Intent(this, MainActivity.class));
- finish();
+ if (isPasswordLogin) {
+ startActivity(new Intent(this, MainActivity.class));
+ finish();
+ } else {
+ qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), qrCode);
+ }
}
}
@@ -307,15 +278,17 @@
}
@Override
- public void obtainFaceLoginData(FaceLoginResultBean resultBean) {
-// Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
- if (resultBean.getCode() == 200) {
+ public void obtainFaceLoginData(FaceResultBean resultBean) {
+ Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
+ if (resultBean.isSuccess()) {
+ //{"code":200,"data":{"kaptcha":"","token":"9135bcb7-4f39-4b7a-a10e-555406ddb9e1"},"exceptionClazz":"","message":"登录成功","success":true}
TokenHelper.saveToken(resultBean.getData().getToken());
//验证成功登录
startActivity(new Intent(this, MainActivity.class));
finish();
} else {
- Toast.makeText(this, "无法解析人脸", Toast.LENGTH_SHORT).show();
+ //{"code":200,"data":"","exceptionClazz":"","message":"图片中没有人脸","success":false}
+ Toast.makeText(this, "人脸识别失败", Toast.LENGTH_SHORT).show();
}
}
@@ -336,5 +309,8 @@
if (qrCodePresenter != null) {
qrCodePresenter.disposeRetrofitRequest();
}
+ if (faceLoginPresenter != null) {
+ faceLoginPresenter.disposeRetrofitRequest();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
index e8e9b75..759a94d 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
@@ -9,4 +9,5 @@
Manifest.permission.WRITE_EXTERNAL_STORAGE};
public static final int PERMISSIONS_CODE = 999;
+ public static final int FACE_DETECTOR_CODE = 998;
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
new file mode 100644
index 0000000..b774ee9
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
@@ -0,0 +1,95 @@
+package com.casic.birmm.hxrq.utils;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.ImageFormat;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.YuvImage;
+import android.util.Base64;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class ImageHelper {
+
+ public ImageHelper(Context context) {
+
+ }
+
+ public Bitmap nv21ToBitmap(byte[] nv21, int width, int height) {
+ Bitmap bitmap = null;
+ try {
+ final YuvImage image = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ image.compressToJpeg(new Rect(0, 0, width, height), 80, outputStream);
+ final Bitmap bmp = BitmapFactory.decodeByteArray(outputStream.toByteArray(), 0, outputStream.size());
+ bitmap = rotateImageView(-90, bmp);
+ outputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return bitmap;
+ }
+
+ public Bitmap rotateImageView(int angle, Bitmap bitmap) {
+ //旋转图片 动作
+ Matrix matrix = new Matrix();
+ matrix.postRotate(angle);
+ // 创建新的图片
+ return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(File file) {
+ if (file == null) {
+ return null;
+ }
+ try {
+ FileInputStream fis = new FileInputStream(file);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] b = new byte[1024];
+ int n;
+ while ((n = fis.read(b)) != -1) {
+ bos.write(b, 0, n);
+ }
+ fis.close();
+ bos.close();
+
+ byte[] imgBytes = bos.toByteArray();
+ String result = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(Bitmap bitmap) {
+ if (bitmap == null) {
+ return null;
+ }
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);//压缩质量
+
+ outputStream.flush();
+ outputStream.close();
+
+ byte[] bitmapBytes = outputStream.toByteArray();
+ String result = Base64.encodeToString(bitmapBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (IOException e) {
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
index f4af6a5..e7772dd 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
@@ -3,33 +3,26 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
-import android.util.Log;
public class SaveKeyValues {
- private static final String TAG = "SaveKeyValues";
-
- @SuppressLint({"StaticFieldLeak"})
- private static Context context;
private static SharedPreferences sharedPreferences;
private static SharedPreferences.Editor editor;
- private static String fileName;
+ @SuppressLint("CommitPrefEdits")
public static void initSharedPreferences(Context mContext) {
- context = mContext.getApplicationContext();
- String packageName = context.getPackageName();
+ String packageName = mContext.getPackageName();
//获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms
String[] split = packageName.split("\\.");//先转义.之后才能分割
int length = split.length;
- fileName = split[length - 1];
- Log.d(TAG, fileName);
+ String fileName = split[length - 1];
+ sharedPreferences = mContext.getSharedPreferences(fileName, Context.MODE_PRIVATE);
+ editor = sharedPreferences.edit();
}
/**
* 存储
*/
public static void putValue(String key, Object object) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
- editor = sharedPreferences.edit();
if (object instanceof String) {
editor.putString(key, (String) object);
} else if (object instanceof Integer) {
@@ -50,7 +43,6 @@
* 获取保存的数据
*/
public static Object getValue(String key, Object defaultObject) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
if (defaultObject instanceof String) {
return sharedPreferences.getString(key, (String) defaultObject);
} else if (defaultObject instanceof Integer) {
@@ -86,7 +78,6 @@
* 查询某个key是否存在
*/
public static boolean containsKey(String key) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
return sharedPreferences.contains(key);
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java
deleted file mode 100644
index 0ebf16a..0000000
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.casic.birmm.hxrq.utils;
-
-import android.util.Base64;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-
-/**
- * @Author: Pengxh
- * @Time: 2021/4/9 15:12
- * @Email: 290677893@qq.com
- **/
-public class StringHelper {
- /**
- * 获取图片base64编码
- */
- public static String imageToBase64(File file) {
- if (file == null) {
- return null;
- }
- try {
- FileInputStream fis = new FileInputStream(file);
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- byte[] b = new byte[1024];
- int n;
- while ((n = fis.read(b)) != -1) {
- bos.write(b, 0, n);
- }
- fis.close();
- bos.close();
-
- byte[] imgBytes = bos.toByteArray();
- String s = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
- return s.replace("-", "+")
- .replace("_", "/");
- } catch (Exception e) {
- return null;
- }
- }
-}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
index 8fe5264..1de1ff4 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.utils.retrofit;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -49,6 +49,6 @@
*/
@Headers({"Content-Type: application/json"})
@POST("/cockpit/face/login")
- Observable getFaceLoginResult(
+ Observable getFaceLoginResult(
@Body ImageBean imageBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java
index ef4307e..d481055 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java
@@ -2,7 +2,7 @@
import android.util.Log;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -10,7 +10,6 @@
import com.casic.birmm.hxrq.utils.HttpConfig;
import org.jetbrains.annotations.NotNull;
-import org.json.JSONObject;
import java.util.concurrent.TimeUnit;
@@ -79,7 +78,7 @@
/**
* 人脸识别登录结果
*/
- public static Observable getFaceResult(String baseUrl, ImageBean imageBean) {
+ public static Observable getFaceResult(String baseUrl, ImageBean imageBean) {
Retrofit retrofit = createRetrofit(baseUrl);
RetrofitService service = retrofit.create(RetrofitService.class);
return service.getFaceLoginResult(imageBean);
diff --git a/app/src/main/res/drawable/bg_circle_image.xml b/app/src/main/res/drawable/bg_circle_image.xml
new file mode 100644
index 0000000..5b27ca4
--- /dev/null
+++ b/app/src/main/res/drawable/bg_circle_image.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_face.xml b/app/src/main/res/layout/activity_face.xml
new file mode 100644
index 0000000..0d2e4e0
--- /dev/null
+++ b/app/src/main/res/layout/activity_face.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
index b300663..5e16fcb 100644
--- a/app/src/main/res/layout/activity_login.xml
+++ b/app/src/main/res/layout/activity_login.xml
@@ -74,8 +74,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/loginButton"
- android:layout_marginTop="20dp"
android:gravity="center"
+ android:paddingVertical="20dp"
android:text="换个方式登录"
android:textColor="@color/mainThemeColor"
android:textSize="@dimen/textFontSize" />
diff --git a/app/build.gradle b/app/build.gradle
index 9d60011..5577e3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,8 +30,7 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
@@ -60,6 +59,4 @@
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.5.0'
- //图片压缩框架
- implementation 'top.zibin:Luban:1.1.8'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6065dc..dceb8c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,8 @@
+
+
@@ -29,6 +31,7 @@
+
observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
- return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
+ Observable observable = RetrofitServiceManager.getFaceResult(HttpConfig.BASE_IP, image);
+ return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
@Override
public void onCompleted() {
@@ -50,7 +50,7 @@
}
@Override
- public void onNext(FaceLoginResultBean resultBean) {
+ public void onNext(FaceResultBean resultBean) {
if (resultBean != null) {
listener.onSuccess(resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
index aac04d9..c9e56be 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/AuthenticatePresenterImpl.java
@@ -29,10 +29,12 @@
@Override
public void onSuccess(PublicKeyBean resultBean) {
+ view.hideProgress();
view.authenticateResult(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
index 7fb154c..d4b110f 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/FaceLoginPresenterImpl.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.mvp.presenter;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.mvp.BasePresenter;
import com.casic.birmm.hxrq.mvp.model.FaceLoginModelImpl;
@@ -23,6 +23,7 @@
@Override
public void onReadyRetrofitRequest(ImageBean image) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(image));
}
@@ -33,12 +34,13 @@
@Override
- public void onSuccess(FaceLoginResultBean resultBean) {
+ public void onSuccess(FaceResultBean resultBean) {
+ view.hideProgress();
view.obtainFaceLoginData(resultBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
index 44cd8a7..31d88bf 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/LoginPresenterImpl.java
@@ -18,6 +18,7 @@
@Override
public void onReadyRetrofitRequest(String sid, String username, String key) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(sid, username, key));
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
index be065db..071a285 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/presenter/QrCodePresenterImpl.java
@@ -17,6 +17,7 @@
@Override
public void onReadyRetrofitRequest(String token, String qrcodeId) {
+ view.showProgress();
addSubscription(actionModel.sendRetrofitRequest(token, qrcodeId));
}
@@ -27,11 +28,12 @@
@Override
public void onSuccess(QrCodeBean codeBean) {
+ view.hideProgress();
view.obtainQrCodeData(codeBean);
}
@Override
public void onFailure(Throwable throwable) {
-
+ view.hideProgress();
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
index 2936b0a..4d8e949 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IAuthenticateView.java
@@ -9,5 +9,7 @@
public interface IAuthenticateView {
void showProgress();
+ void hideProgress();
+
void authenticateResult(PublicKeyBean result);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
index c6d3e33..7e502f2 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IFaceLoginView.java
@@ -1,7 +1,11 @@
package com.casic.birmm.hxrq.mvp.view;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
public interface IFaceLoginView {
- void obtainFaceLoginData(FaceLoginResultBean resultBean);
+ void showProgress();
+
+ void hideProgress();
+
+ void obtainFaceLoginData(FaceResultBean resultBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
index c9783cd..fe666b1 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/ILoginView.java
@@ -3,6 +3,8 @@
import com.casic.birmm.hxrq.bean.LoginResultBean;
public interface ILoginView {
+ void showProgress();
+
void hideProgress();
void obtainLoginResult(LoginResultBean resultBean);
diff --git a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
index 4e8821e..4003e26 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/mvp/view/IQrCodeDataView.java
@@ -3,5 +3,9 @@
import com.casic.birmm.hxrq.bean.QrCodeBean;
public interface IQrCodeDataView {
+ void showProgress();
+
+ void hideProgress();
+
void obtainQrCodeData(QrCodeBean userBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
new file mode 100644
index 0000000..4109e3c
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java
@@ -0,0 +1,184 @@
+package com.casic.birmm.hxrq.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.ImageFormat;
+import android.hardware.Camera;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import androidx.annotation.NonNull;
+
+import com.casic.birmm.hxrq.R;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.utils.ImageHelper;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Stack;
+
+import butterknife.BindView;
+
+public class FacePreViewActivity extends BaseActivity implements Camera.PreviewCallback {
+
+ private static final int preViewWidth = 720;
+ private static final int preViewHeight = 1280;
+ @BindView(R.id.surfaceView)
+ SurfaceView surfaceView;
+ private SurfaceHolder mSurfaceHolder;
+ private Camera mCamera;
+ private ImageHelper imageHelper;
+ private Stack bitmapStack;
+ private boolean isCanLogin = true;
+
+ @Override
+ public int initLayoutView() {
+ return R.layout.activity_face;
+ }
+
+ @Override
+ protected void setupTopBarLayout() {
+
+ }
+
+ @Override
+ public void initData() {
+ imageHelper = new ImageHelper(this);
+ bitmapStack = new Stack<>();
+ }
+
+ @Override
+ public void initEvent() {
+ // 绑定SurfaceView,取得SurfaceHolder对象
+ mSurfaceHolder = surfaceView.getHolder();
+ mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(@NonNull SurfaceHolder holder) {
+ if (mCamera == null) {
+ //打开相机
+ openCamera();
+ }
+ try {
+ //预览画面
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ //开始预览
+ mCamera.startPreview();
+ }
+
+ @Override
+ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
+
+ }
+
+ @Override
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+ releaseCamera(); //释放相机资源
+ }
+ });
+ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置
+ }
+
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ camera.addCallbackBuffer(data);
+ Camera.Size size = camera.getParameters().getPreviewSize();//必须是相机支持的预览尺寸,否则颜色YUV空间会错位
+ Bitmap originBitmap = imageHelper.nv21ToBitmap(data, size.width, size.height);
+ //要使用Android内置的人脸识别,需要将Bitmap对象转为RGB_565格式,否则无法识别
+// Bitmap faceDetectorBitmap = originBitmap.copy(Bitmap.Config.RGB_565, true);
+// FaceDetector.Face[] faces = new FaceDetector.Face[1];
+// FaceDetector faceDetector = new FaceDetector(faceDetectorBitmap.getWidth(), faceDetectorBitmap.getHeight(), 1);
+// int faceSum = faceDetector.findFaces(faceDetectorBitmap, faces);
+// if (faceSum == 1) {
+ bitmapStack.push(originBitmap);
+ if (bitmapStack.size() >= 5) {//当栈里有5张bitmap之后才开始识别
+ if (isCanLogin) {
+ isCanLogin = false;
+ Bitmap bitmap = bitmapStack.pop();
+ Intent intent = new Intent();
+ intent.putExtra("imageToBase64", ImageHelper.imageToBase64(bitmap));
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ } else {
+ finish();
+ }
+ }
+// } else {
+// Log.d(TAG, "detectorFace: 未检测到人脸");
+// }
+ }
+
+ /**
+ * 打开相机
+ */
+ private void openCamera() {
+ try {
+ mCamera = Camera.open(1);
+ initParameters(mCamera); //初始化相机配置信息
+ mCamera.setPreviewCallback(this);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 初始化相机属性
+ */
+ private void initParameters(Camera camera) {
+ try {
+ Camera.Parameters mParameters = camera.getParameters();
+ mParameters.setPreviewFormat(ImageFormat.NV21); //设置预览图片的格式
+ //获取与指定宽高相等或最接近的尺寸
+ //设置预览尺寸
+ Camera.Size bestPreviewSize = obtainBestSize(preViewWidth, preViewHeight, mParameters.getSupportedPreviewSizes());
+ mParameters.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height);
+ //设置保存图片尺寸
+// Camera.Size bestPicSize = obtainBestSize(picWidth, picHeight, mParameters.getSupportedPictureSizes());
+// mParameters.setPictureSize(bestPicSize.width, bestPicSize.height);
+ //对焦模式
+ mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ camera.setDisplayOrientation(90);
+ camera.setParameters(mParameters);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 获取最合适的尺寸
+ */
+ private Camera.Size obtainBestSize(int targetWidth, int targetHeight, List sizeList) {
+ Camera.Size bestSize = null;
+ int targetRatio = targetHeight / targetWidth;//目标大小的宽高比
+ int minDiff = targetRatio;
+
+ for (Camera.Size size : sizeList) {
+ if (size.width == targetHeight && size.height == targetWidth) {
+ bestSize = size;
+ break;
+ }
+ int supportedRatio = (size.width / size.height);
+ if (Math.abs(supportedRatio - targetRatio) < minDiff) {
+ minDiff = Math.abs(supportedRatio - targetRatio);
+ bestSize = size;
+ }
+ }
+ return bestSize;
+ }
+
+ /**
+ * 释放相机资源
+ */
+ private void releaseCamera() {
+ if (mCamera != null) {
+ mCamera.stopPreview();
+ mCamera.setPreviewCallback(null);
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
index 98aef9d..30c26c8 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/ui/LoginActivity.java
@@ -8,14 +8,15 @@
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.casic.birmm.hxrq.R;
-import com.casic.birmm.hxrq.base.DoubleClickExitActivity;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.base.BaseActivity;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -28,23 +29,16 @@
import com.casic.birmm.hxrq.mvp.view.IFaceLoginView;
import com.casic.birmm.hxrq.mvp.view.ILoginView;
import com.casic.birmm.hxrq.mvp.view.IQrCodeDataView;
-import com.casic.birmm.hxrq.utils.FileUtils;
-import com.casic.birmm.hxrq.utils.GlideLoadEngine;
+import com.casic.birmm.hxrq.utils.Constant;
import com.casic.birmm.hxrq.utils.RSAUtils;
import com.casic.birmm.hxrq.utils.SaveKeyValues;
-import com.casic.birmm.hxrq.utils.StringHelper;
import com.casic.birmm.hxrq.utils.TokenHelper;
import com.google.gson.Gson;
-import com.luck.picture.lib.PictureSelector;
-import com.luck.picture.lib.config.PictureConfig;
-import com.luck.picture.lib.config.PictureMimeType;
-import com.luck.picture.lib.entity.LocalMedia;
import com.qmuiteam.qmui.util.QMUIStatusBarHelper;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton;
-import java.io.File;
import java.security.PublicKey;
import butterknife.BindView;
@@ -53,15 +47,11 @@
import cn.bertsir.zbar.QrConfig;
import cn.bertsir.zbar.QrManager;
import cn.bertsir.zbar.view.ScanLineView;
-import top.zibin.luban.CompressionPredicate;
-import top.zibin.luban.Luban;
-import top.zibin.luban.OnCompressListener;
-public class LoginActivity extends DoubleClickExitActivity
- implements View.OnClickListener, IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
+public class LoginActivity extends BaseActivity implements View.OnClickListener,
+ IAuthenticateView, ILoginView, IQrCodeDataView, IFaceLoginView {
private static final String TAG = "LoginActivity";
-
@BindView(R.id.userNameView)
EditText userNameView;
@BindView(R.id.userPasswordView)
@@ -76,8 +66,8 @@
private LoginPresenterImpl loginPresenter;
private QrCodePresenterImpl qrCodePresenter;
private FaceLoginPresenterImpl faceLoginPresenter;
- private String userName;
- private String userPassword;
+ private boolean isPasswordLogin = false;
+ private String qrCode = "";
@Override
public int initLayoutView() {
@@ -86,20 +76,29 @@
@Override
protected void setupTopBarLayout() {
- //TODO 此页面无需实现
+ //设置状态栏黑色字体图标
+ QMUIStatusBarHelper.setStatusBarLightMode(this);
}
@Override
public void initData() {
- //设置状态栏黑色字体图标
- QMUIStatusBarHelper.setStatusBarLightMode(this);
-
String userName = (String) SaveKeyValues.getValue("userName", "");
String userPassword = (String) SaveKeyValues.getValue("userPassword", "");
+ userNameView.setText(userName);
+ userPasswordView.setText(userPassword);
if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) {
- userNameView.setText(userName);
- userPasswordView.setText(userPassword);
+ rememberPasswordView.setChecked(true);
+ } else {
+ rememberPasswordView.setChecked(false);
}
+ rememberPasswordView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (!isChecked) {
+ SaveKeyValues.removeKey("userPassword");
+ }
+ }
+ });
loadingDialog = new QMUITipDialog.Builder(this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
.setTipWord("登陆中,请稍后")
@@ -124,14 +123,9 @@
public void onClick(View v) {
switch (v.getId()) {
case R.id.loginButton:
- userName = userNameView.getText().toString();
- userPassword = userPasswordView.getText().toString();
- if (rememberPasswordView.isChecked()) {
- SaveKeyValues.putValue("userName", userName);
- SaveKeyValues.putValue("userPassword", userPassword);
- }
//密码登录前需要验证sid
authenticatePresenter.onReadyRetrofitRequest();
+ isPasswordLogin = true;
break;
case R.id.changeLoginModeView:
//首次登录不可用扫码,因为还未注册
@@ -169,50 +163,19 @@
}
private void captureFaceData() {
- //TODO 调相机,捕获人脸数据,并保存为文件得到路径
- PictureSelector.create(this)
- .openCamera(PictureMimeType.ofImage())
- .imageEngine(GlideLoadEngine.createGlideEngine())
- .maxSelectNum(1)
- .forResult(PictureConfig.REQUEST_CAMERA);
+ // 调相机,捕获人脸数据,并保存为文件得到路径
+ startActivityForResult(new Intent(this, FacePreViewActivity.class), Constant.FACE_DETECTOR_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
- if (requestCode == PictureConfig.REQUEST_CAMERA) {
- LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0);
- Luban.with(this)
- .load(localMedia.getRealPath())
- .ignoreBy(100)
- .setTargetDir(FileUtils.getFileDir("CompressImageFile"))
- .filter(new CompressionPredicate() {
- @Override
- public boolean apply(String path) {
- return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));
- }
- })
- .setCompressListener(new OnCompressListener() {
- @Override
- public void onStart() {
- // TODO 压缩开始前调用,可以在方法内启动 loading UI
- }
-
- @Override
- public void onSuccess(File file) {
- String imageToBase64 = StringHelper.imageToBase64(file);
-
- ImageBean imageBean = new ImageBean();
- imageBean.setImage(imageToBase64);
- faceLoginPresenter.onReadyRetrofitRequest(imageBean);
- }
-
- @Override
- public void onError(Throwable e) {
- // TODO 当压缩过程出现问题时调用
- }
- }).launch();
+ if (requestCode == Constant.FACE_DETECTOR_CODE) {
+ String imageToBase64 = data.getStringExtra("imageToBase64");
+ ImageBean imageBean = new ImageBean();
+ imageBean.setImage(imageToBase64);
+ faceLoginPresenter.onReadyRetrofitRequest(imageBean);
}
}
}
@@ -232,7 +195,7 @@
.setPlaySound(true)//是否扫描成功后bi~的声音
.setDingPath(R.raw.qrcode)//设置提示音(不设置为默认的Ding~)
.setIsOnlyCenter(true)//是否只识别框中内容(默认为全屏识别)
- .setTitleBackgroudColor(Color.parseColor("#262020"))//设置状态栏颜色
+ .setTitleBackgroudColor(R.color.black)//设置状态栏颜色
.setTitleTextColor(Color.WHITE)//设置Title文字颜色
.setScreenOrientation(QrConfig.SCREEN_PORTRAIT)//设置屏幕方式
.setScanLineStyle(ScanLineView.style_hybrid)//扫描线样式
@@ -241,8 +204,8 @@
QrManager.getInstance().init(qrConfig).startScan(this, new QrManager.OnScanResultCallback() {
@Override
public void onScanSuccess(final ScanResult result) {
-// Log.d(TAG, "扫码结果: " + result.content);
- qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), result.content);
+ qrCode = result.content;
+ authenticatePresenter.onReadyRetrofitRequest();//需要时时保持最新token,所以扫码登录之前需要获取最新token
}
});
}
@@ -254,9 +217,15 @@
@Override
public void authenticateResult(PublicKeyBean result) {
- Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
+// Log.d(TAG, "authenticateResult: " + new Gson().toJson(result));
if (result.isSuccess()) {
PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey());
+ String userName = userNameView.getText().toString();
+ String userPassword = userPasswordView.getText().toString();
+ if (rememberPasswordView.isChecked()) {
+ SaveKeyValues.putValue("userName", userName);
+ SaveKeyValues.putValue("userPassword", userPassword);
+ }
if (TextUtils.isEmpty(userName)) {
Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show();
return;
@@ -266,7 +235,6 @@
return;
}
String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey);
- Log.d(TAG, "authenticateResult: 验证成功,开始登录");
//登录并获取Token,POST请求
loginPresenter.onReadyRetrofitRequest(result.getData().getSid(), userName, dataByPublicKey);
} else {
@@ -283,11 +251,14 @@
String token = result.getData().getToken();
if (!TextUtils.isEmpty(token)) {
//获取用户信息
- Log.d(TAG, "obtainLoginResult: 获取Token成功");
TokenHelper.saveToken(token);
//验证成功登录
- startActivity(new Intent(this, MainActivity.class));
- finish();
+ if (isPasswordLogin) {
+ startActivity(new Intent(this, MainActivity.class));
+ finish();
+ } else {
+ qrCodePresenter.onReadyRetrofitRequest(TokenHelper.getToken(), qrCode);
+ }
}
}
@@ -307,15 +278,17 @@
}
@Override
- public void obtainFaceLoginData(FaceLoginResultBean resultBean) {
-// Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
- if (resultBean.getCode() == 200) {
+ public void obtainFaceLoginData(FaceResultBean resultBean) {
+ Log.d(TAG, "obtainFaceLoginData: " + new Gson().toJson(resultBean));
+ if (resultBean.isSuccess()) {
+ //{"code":200,"data":{"kaptcha":"","token":"9135bcb7-4f39-4b7a-a10e-555406ddb9e1"},"exceptionClazz":"","message":"登录成功","success":true}
TokenHelper.saveToken(resultBean.getData().getToken());
//验证成功登录
startActivity(new Intent(this, MainActivity.class));
finish();
} else {
- Toast.makeText(this, "无法解析人脸", Toast.LENGTH_SHORT).show();
+ //{"code":200,"data":"","exceptionClazz":"","message":"图片中没有人脸","success":false}
+ Toast.makeText(this, "人脸识别失败", Toast.LENGTH_SHORT).show();
}
}
@@ -336,5 +309,8 @@
if (qrCodePresenter != null) {
qrCodePresenter.disposeRetrofitRequest();
}
+ if (faceLoginPresenter != null) {
+ faceLoginPresenter.disposeRetrofitRequest();
+ }
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
index e8e9b75..759a94d 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/Constant.java
@@ -9,4 +9,5 @@
Manifest.permission.WRITE_EXTERNAL_STORAGE};
public static final int PERMISSIONS_CODE = 999;
+ public static final int FACE_DETECTOR_CODE = 998;
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
new file mode 100644
index 0000000..b774ee9
--- /dev/null
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/ImageHelper.java
@@ -0,0 +1,95 @@
+package com.casic.birmm.hxrq.utils;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.ImageFormat;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.YuvImage;
+import android.util.Base64;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class ImageHelper {
+
+ public ImageHelper(Context context) {
+
+ }
+
+ public Bitmap nv21ToBitmap(byte[] nv21, int width, int height) {
+ Bitmap bitmap = null;
+ try {
+ final YuvImage image = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ image.compressToJpeg(new Rect(0, 0, width, height), 80, outputStream);
+ final Bitmap bmp = BitmapFactory.decodeByteArray(outputStream.toByteArray(), 0, outputStream.size());
+ bitmap = rotateImageView(-90, bmp);
+ outputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return bitmap;
+ }
+
+ public Bitmap rotateImageView(int angle, Bitmap bitmap) {
+ //旋转图片 动作
+ Matrix matrix = new Matrix();
+ matrix.postRotate(angle);
+ // 创建新的图片
+ return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(File file) {
+ if (file == null) {
+ return null;
+ }
+ try {
+ FileInputStream fis = new FileInputStream(file);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] b = new byte[1024];
+ int n;
+ while ((n = fis.read(b)) != -1) {
+ bos.write(b, 0, n);
+ }
+ fis.close();
+ bos.close();
+
+ byte[] imgBytes = bos.toByteArray();
+ String result = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 获取图片base64编码
+ */
+ public static String imageToBase64(Bitmap bitmap) {
+ if (bitmap == null) {
+ return null;
+ }
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);//压缩质量
+
+ outputStream.flush();
+ outputStream.close();
+
+ byte[] bitmapBytes = outputStream.toByteArray();
+ String result = Base64.encodeToString(bitmapBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
+ return result.replace("-", "+")
+ .replace("_", "/");
+ } catch (IOException e) {
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
index f4af6a5..e7772dd 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/SaveKeyValues.java
@@ -3,33 +3,26 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
-import android.util.Log;
public class SaveKeyValues {
- private static final String TAG = "SaveKeyValues";
-
- @SuppressLint({"StaticFieldLeak"})
- private static Context context;
private static SharedPreferences sharedPreferences;
private static SharedPreferences.Editor editor;
- private static String fileName;
+ @SuppressLint("CommitPrefEdits")
public static void initSharedPreferences(Context mContext) {
- context = mContext.getApplicationContext();
- String packageName = context.getPackageName();
+ String packageName = mContext.getPackageName();
//获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms
String[] split = packageName.split("\\.");//先转义.之后才能分割
int length = split.length;
- fileName = split[length - 1];
- Log.d(TAG, fileName);
+ String fileName = split[length - 1];
+ sharedPreferences = mContext.getSharedPreferences(fileName, Context.MODE_PRIVATE);
+ editor = sharedPreferences.edit();
}
/**
* 存储
*/
public static void putValue(String key, Object object) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
- editor = sharedPreferences.edit();
if (object instanceof String) {
editor.putString(key, (String) object);
} else if (object instanceof Integer) {
@@ -50,7 +43,6 @@
* 获取保存的数据
*/
public static Object getValue(String key, Object defaultObject) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
if (defaultObject instanceof String) {
return sharedPreferences.getString(key, (String) defaultObject);
} else if (defaultObject instanceof Integer) {
@@ -86,7 +78,6 @@
* 查询某个key是否存在
*/
public static boolean containsKey(String key) {
- sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
return sharedPreferences.contains(key);
}
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java b/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java
deleted file mode 100644
index 0ebf16a..0000000
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/StringHelper.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.casic.birmm.hxrq.utils;
-
-import android.util.Base64;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-
-/**
- * @Author: Pengxh
- * @Time: 2021/4/9 15:12
- * @Email: 290677893@qq.com
- **/
-public class StringHelper {
- /**
- * 获取图片base64编码
- */
- public static String imageToBase64(File file) {
- if (file == null) {
- return null;
- }
- try {
- FileInputStream fis = new FileInputStream(file);
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- byte[] b = new byte[1024];
- int n;
- while ((n = fis.read(b)) != -1) {
- bos.write(b, 0, n);
- }
- fis.close();
- bos.close();
-
- byte[] imgBytes = bos.toByteArray();
- String s = Base64.encodeToString(imgBytes, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
- return s.replace("-", "+")
- .replace("_", "/");
- } catch (Exception e) {
- return null;
- }
- }
-}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
index 8fe5264..1de1ff4 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitService.java
@@ -1,6 +1,6 @@
package com.casic.birmm.hxrq.utils.retrofit;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -49,6 +49,6 @@
*/
@Headers({"Content-Type: application/json"})
@POST("/cockpit/face/login")
- Observable getFaceLoginResult(
+ Observable getFaceLoginResult(
@Body ImageBean imageBean);
}
diff --git a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java
index ef4307e..d481055 100644
--- a/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java
+++ b/app/src/main/java/com/casic/birmm/hxrq/utils/retrofit/RetrofitServiceManager.java
@@ -2,7 +2,7 @@
import android.util.Log;
-import com.casic.birmm.hxrq.bean.FaceLoginResultBean;
+import com.casic.birmm.hxrq.bean.FaceResultBean;
import com.casic.birmm.hxrq.bean.ImageBean;
import com.casic.birmm.hxrq.bean.LoginResultBean;
import com.casic.birmm.hxrq.bean.PublicKeyBean;
@@ -10,7 +10,6 @@
import com.casic.birmm.hxrq.utils.HttpConfig;
import org.jetbrains.annotations.NotNull;
-import org.json.JSONObject;
import java.util.concurrent.TimeUnit;
@@ -79,7 +78,7 @@
/**
* 人脸识别登录结果
*/
- public static Observable getFaceResult(String baseUrl, ImageBean imageBean) {
+ public static Observable getFaceResult(String baseUrl, ImageBean imageBean) {
Retrofit retrofit = createRetrofit(baseUrl);
RetrofitService service = retrofit.create(RetrofitService.class);
return service.getFaceLoginResult(imageBean);
diff --git a/app/src/main/res/drawable/bg_circle_image.xml b/app/src/main/res/drawable/bg_circle_image.xml
new file mode 100644
index 0000000..5b27ca4
--- /dev/null
+++ b/app/src/main/res/drawable/bg_circle_image.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_face.xml b/app/src/main/res/layout/activity_face.xml
new file mode 100644
index 0000000..0d2e4e0
--- /dev/null
+++ b/app/src/main/res/layout/activity_face.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
index b300663..5e16fcb 100644
--- a/app/src/main/res/layout/activity_login.xml
+++ b/app/src/main/res/layout/activity_login.xml
@@ -74,8 +74,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/loginButton"
- android:layout_marginTop="20dp"
android:gravity="center"
+ android:paddingVertical="20dp"
android:text="换个方式登录"
android:textColor="@color/mainThemeColor"
android:textSize="@dimen/textFontSize" />
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 8da4e0c..00a79de 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,6 +1,5 @@
-
+