diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4d73080..b29c2a4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,18 +4,18 @@ package="com.dskj.daikuan"> - - - - - - - - - - - - + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/verification/.idea/misc.xml b/verification/.idea/misc.xml new file mode 100644 index 0000000..46fefaa --- /dev/null +++ b/verification/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/verification/.idea/modules.xml b/verification/.idea/modules.xml new file mode 100644 index 0000000..84d987c --- /dev/null +++ b/verification/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/verification/.idea/vcs.xml b/verification/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/verification/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/verification/build.gradle b/verification/build.gradle new file mode 100644 index 0000000..6c4a2f8 --- /dev/null +++ b/verification/build.gradle @@ -0,0 +1,119 @@ +plugins { + id 'com.android.application' + id 'kotlin-android' +} + +android { + compileSdk 31 + + defaultConfig { + applicationId "com.dskj.verification" + minSdkVersion 23 + targetSdk 30 + versionCode 133 + versionName "1.3.3" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" +// configurations.all { +// resolutionStrategy { force 'androidx.core:core-ktx:1.6.0' } +// } + ndk { + abiFilters "arm64-v8a"//,"armeabi-v7a", "x86", "x86_64" + } + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + debug { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + useLibrary 'org.apache.http.legacy' + //启用DataBinding + buildFeatures{ + dataBinding = true + // for view binding : + // viewBinding = true + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } + + + signingConfigs { + debug { + storeFile file('videomark.jks') + storePassword "123456" + keyAlias 'videomark' + keyPassword "123456" + v1SigningEnabled true + v2SigningEnabled true + } + release { + storeFile file('videomark.jks') + storePassword "123456" + keyAlias 'videomark' + keyPassword "123456" + v1SigningEnabled true + v2SigningEnabled true + + } + } + lintOptions { + checkReleaseBuilds false + abortOnError false + } +} + +configurations.all{ + resolutionStrategy{ + force 'androidx.core:core:1.6.0' + } +} + +dependencies { + implementation 'com.github.tbruyelle:rxpermissions:0.10.2' + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.3.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + testImplementation "junit:junit:4.13.1" + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + //viewmode需要引入的依赖 livedate 之类的就依赖他了 + implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' + + implementation project(path: ':basicLib') + implementation "androidx.fragment:fragment-ktx:1.4.0" + implementation "androidx.core:core-ktx:1.3.2" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation 'io.reactivex:rxjava:1.3.0' + implementation 'io.reactivex:rxandroid:1.2.1' + // okhttp 3 + implementation 'com.squareup.okhttp3:okhttp:3.10.0' + implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0' + + implementation 'com.github.Hitomis:transferee:1.6.1' + // 添加 Glide 图片加载器 + implementation 'com.github.Hitomis.transferee:GlideImageLoader:1.6.1' + implementation 'com.gyf.immersionbar:immersionbar:2.3.3' + + implementation project(path: ':matisse') + + + //以下3个 下拉刷新和加载更多依赖 + implementation 'com.scwang.smart:refresh-layout-kernel:2.0.1' + //核心必须依赖 + implementation 'com.scwang.smart:refresh-header-classics:2.0.1' + //经典刷新头 + implementation 'com.scwang.smart:refresh-footer-classics:2.0.1' + implementation 'com.scwang.smart:refresh-footer-ball:2.0.1' + implementation 'com.github.cazaea:sweet-alert-dialog:1.0.0' + implementation 'com.tencent.bugly:crashreport:4.0.4' + +} \ No newline at end of file diff --git a/verification/proguard-rules.pro b/verification/proguard-rules.pro new file mode 100644 index 0000000..6d5f060 --- /dev/null +++ b/verification/proguard-rules.pro @@ -0,0 +1,451 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile +-keepclassmembers class fqcn.of.javascript.interface.for.webview { + public *; +} +#指定代码的压缩级别 +-optimizationpasses 5 + +#包明不混合大小写 +-dontusemixedcaseclassnames + +#不去忽略非公共的库类 +-dontskipnonpubliclibraryclasses + + #优化 不优化输入的类文件 +-dontoptimize + + #预校验 +-dontpreverify + + #混淆时是否记录日志 +-verbose + + # 混淆时所采用的算法 +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +#忽略警告 +-ignorewarning + + +-keep public class * extends android.app.Fragment +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference + +-keep class com.bikao.cleanmark.view.** { *; } +-keep class com.coremedia.iso.** {*;} +-keep class nu.xom.** {*;} +-keep class com.googlecode.mp4parser.** {*;} +-keep class com.mp4parser.** {*;} +-keep class com.coremedia.iso.** {*;} +-keep class org.aspectj.** {*;} + +-keep class jp.co.recruit_lifestyle.android.floatingview.** {*;} + +# 如果有引用v4包可以添加下面这行 +-keep class android.support.v4.**{ *;} + +# 如果引用了v4或者v7包 +-dontwarn android.support.** + +# 保持 native 方法不被混淆 +-keepclasseswithmembernames class * { + native ; +} + +-keep class com.bikao.dkplayer.** {*;} + +# 保护注解 +-keepattributes *Annotation* +-keep class * extends java.lang.annotation.Annotation {*;} + +# 泛型与反射 +-keepattributes Signature +-keepattributes EnclosingMethod + +# 不混淆内部类 +-keepattributes InnerClasses + +# gson +-dontwarn com.google.** +-keep class com.google.gson.** {*;} + + +#保持枚举 enum 类不被混淆 +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +# otto混淆规则 +-keepattributes *Annotation* +-keepclassmembers class ** { + @com.squareup.otto.Subscribe public *; + @com.squareup.otto.Produce public *; +} +#所有bean都不要混淆 +-keep class * implements java.io.Serializable {*;} +-keepclassmembers class * implements java.io.Serializable {*;} +-keep class * implements java.lang.Comparable {*;} +-keepclassmembers class * implements java.lang.Comparable {*;} +-keep class com.bikao.cleanmark.bean.** { *; } + +#一般网络层都不进行混淆 +-keep class com.xxx.xxx.http.** {*;} + +#如果你遇到一些控件无法Inflate,报NullPointException,比如ListView,NavigationView等等 +#-keep class org.xmlpull.v1.** {*;} + +# OkHttp +-dontwarn com.squareup.okhttp.** +-keep class com.squareup.okhttp.** {*;} +-keep interface com.squareup.okhttp.** {*;} +-dontwarn okio.** + +# Realm +-keep class io.realm.annotations.RealmModule +-keep @io.realm.annotations.RealmModule class * +-keep class io.realm.internal.Keep +-keep @io.realm.internal.Keep class * { *; } +-dontwarn javax.** +-dontwarn io.realm.** + +#友盟 +-keep class com.umeng.** {*;} + +-keep class com.uc.** {*;} + +-keepclassmembers class * { + public (org.json.JSONObject); +} +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} +-keep class com.zui.** {*;} +-keep class com.miui.** {*;} +-keep class com.heytap.** {*;} +-keep class a.** {*;} +-keep class com.vivo.** {*;} + +-keep public class com.adwl.location.R$*{ +public static final int *; +} + +#lambda +-dontwarn java.lang.invoke.* +-dontwarn **$$Lambda$* + +#基线包使用,生成mapping.txt +-printmapping mapping.txt +#生成的mapping.txt在app/buidl/outputs/mapping/release路径下,移动到/app路径下 + +#修复后的项目使用,保证混淆结果一致 +#-applymapping mapping.txt + +#Glide +-keep public class * implements com.bumptech.glide.module.GlideModule +-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { + **[] $VALUES; + public *; +} + +-keep class com.bytedance.sdk.openadsdk.** { *; } +-keep public interface com.bytedance.sdk.openadsdk.downloadnew.** {*;} +-keep class com.pgl.sys.ces.* {*;} + +# for DexGuard only +#-keepresourcexmlelements manifest/application/meta-data@value=GlideModule + +#butterknife + -dontwarn butterknife.internal.** +# -keep class butterknife.** { *; } +# -dontwarn butterknife.internal.** +# -keep class **$$ViewBinder { *; } +# -keepclasseswithmembernames class * { @butterknife.* ;} +# -keepclasseswithmembernames class * { @butterknife.* ;} + +#SweetAlert +-keep class cn.pedant.SweetAlert.**{*;} +-keep class cn.pedant.SweetAlert.Rotate3dAnimation { + public (...); +} + +#retrofit2 +# Platform calls Class.forName on typeswhich do not exist on Android to determine platform. +-dontnote retrofit2.Platform + +# Platform used when running on RoboVM oniOS. Will not be used at runtime. +-dontnote retrofit2.Platform$IOS$MainThreadExecutor + +# Platform used when running on Java 8 VMs.Will not be used at runtime. +-dontwarn retrofit2.Platform$Java8 + +# Retain generic type information for useby reflection by converters and adapters. +-keepattributes Signature + +# Retain declared checked exceptions foruse by a Proxy instance. +-keepattributes Exceptions + +# Retrofit +-dontwarn retrofit2.** +-keep class retrofit2.** { *; } + +# Retrolambda +-dontwarn java.lang.invoke.* + + +# RxJava RxAndroid +-dontwarn sun.misc.** +-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { + long producerIndex; + long consumerIndex; +} +-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef { + rx.internal.util.atomic.LinkedQueueNode producerNode; +} +-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { + rx.internal.util.atomic.LinkedQueueNode consumerNode; +} + +# EventBus混淆 +-keepclassmembers class ** { + public void onEvent*(***); +} +# Only required if you use AsyncExecutor +-keepclassmembers class * extends de.greenrobot.event.util.ThrowableFailureEvent { + public (java.lang.Throwable); +} +# Don't warn for missing support classes +-dontwarn de.greenrobot.event.util.*$Support +-dontwarn de.greenrobot.event.util.*$SupportManagerFragment + +-keep class com.gyf.immersionbar.* {*;} + -dontwarn com.gyf.immersionbar.** + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep public class com.bikao.cleanmark.R$*{ +public static final int *; +} + +#ijk +#ijkplayer +-keep class tv.danmaku.ijk.media.player.** {*;} +-keep class tv.danmaku.ijk.media.player.IjkMediaPlayer{*;} +-keep class tv.danmaku.ijk.media.player.ffmpeg.FFmpegApi{*;} + +# //smack + -keep class org.jxmpp.** {*;} + -keep class de.measite.** {*;} + -keep class org.jivesoftware.** {*;} + -keep class org.xmlpull.** {*;} + -dontwarn org.xbill.** + -keep class org.xbill.** {*;} + +# //eventbus + -keepattributes *Annotation* + -keepclassmembers class ** { + @org.greenrobot.eventbus.Subscribe ; + } + -keep enum org.greenrobot.eventbus.ThreadMode { *; } + + # Only required if you use AsyncExecutor + -keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { + (java.lang.Throwable); + } + + -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip + -keep @com.facebook.common.internal.DoNotStrip class * + -keepclassmembers class * { + @com.facebook.common.internal.DoNotStrip *; + } + # Keep native methods + -keepclassmembers class * { + native ; + } + + -dontwarn okio.** + -dontwarn com.squareup.okhttp.** + -dontwarn okhttp3.** + -dontwarn javax.annotation.** + -dontwarn com.android.volley.toolbox.** + -dontwarn com.facebook.infer.** + + + + -keep class com.iflytek.**{*;} + +#UShare +-dontshrink +-dontoptimize +-dontwarn com.google.android.maps.** +-dontwarn android.webkit.WebView +-dontwarn com.umeng.** +-dontwarn com.tencent.weibo.sdk.** +-dontwarn com.facebook.** +-keep public class javax.** +-keep public class android.webkit.** +-dontwarn android.support.v4.** +-keep enum com.facebook.** +-keepattributes Exceptions,InnerClasses,Signature +-keepattributes *Annotation* +-keepattributes SourceFile,LineNumberTable +-keep public interface com.facebook.** +-keep public interface com.tencent.** +-keep public interface com.umeng.socialize.** +-keep public interface com.umeng.socialize.sensor.** +-keep public interface com.umeng.scrshot.** +-keep public class com.umeng.socialize.* {*;} +-keep class com.facebook.** +-keep class com.facebook.** { *; } +-keep class com.umeng.scrshot.** +-keep public class com.tencent.** {*;} +-keep class com.umeng.socialize.sensor.** +-keep class com.umeng.socialize.handler.** +-keep class com.umeng.socialize.handler.* +-keep class com.umeng.weixin.handler.** +-keep class com.umeng.weixin.handler.* +-keep class com.umeng.qq.handler.** +-keep class com.umeng.qq.handler.* +-keep class UMMoreHandler{*;} +-keep class com.tencent.mm.sdk.modelmsg.WXMediaMessage {*;} +-keep class com.tencent.mm.sdk.modelmsg.** implements com.tencent.mm.sdk.modelmsg.WXMediaMessage$IMediaObject {*;} +-keep class im.yixin.sdk.api.YXMessage {*;} +-keep class im.yixin.sdk.api.** implements im.yixin.sdk.api.YXMessage$YXMessageData{*;} +-keep class com.tencent.mm.sdk.** { + *; +} +-keep class com.tencent.mm.opensdk.** { + *; +} +-keep class com.tencent.wxop.** { + *; +} +-keep class com.tencent.mm.sdk.** { + *; +} +-keep class com.umeng.** {*;} +-dontwarn twitter4j.** +-keep class twitter4j.** { *; } +-keep class com.tencent.** {*;} +-dontwarn com.tencent.** +-keep class com.kakao.** {*;} +-dontwarn com.kakao.** +-keep public class com.umeng.com.umeng.soexample.R$*{ + public static final int *; +} +-keep public class com.linkedin.android.mobilesdk.R$*{ + public static final int *; +} +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} +-keep class com.tencent.open.TDialog$* +-keep class com.tencent.open.TDialog$* {*;} +-keep class com.tencent.open.PKDialog +-keep class com.tencent.open.PKDialog {*;} +-keep class com.tencent.open.PKDialog$* +-keep class com.tencent.open.PKDialog$* {*;} +-keep class com.umeng.socialize.impl.ImageImpl {*;} +-keep class com.sina.** {*;} +-dontwarn com.sina.** +-keep class com.alipay.share.sdk.** { + *; +} +-keep class * implements android.os.Parcelable {*;} + +-keepnames class * implements android.os.Parcelable { + public static final ** CREATOR; +} +-keepclassmembers class * implements android.os.Parcelable {*;} + +-keep class com.linkedin.** { *; } +-keep class com.android.dingtalk.share.ddsharemodule.** { *; } +-keepattributes Signature +#UShare + + +# 请开发者根据自己实际情况给第三方库的添加相应的混淆设置 +-dontwarn com.androidquery.** +-keep class com.androidquery.** { *;} + +-dontwarn tv.danmaku.** +-keep class tv.danmaku.** { *;} + +-dontwarn androidx.** + +# 如果使用了tbs版本的sdk需要进行以下配置 +-keep class com.tencent.smtt.** { *; } +-dontwarn dalvik.** +-dontwarn com.tencent.smtt.** + +-keep class com.google.android.exoplayer2.** { *; } +-dontwarn com.google.android.exoplayer2.** + +-keep class com.aplayer.** { *; } +-dontwarn com.aplayer.** + +-dontwarn com.tencent.bugly.** +-keep public class com.tencent.bugly.**{*;} + + +-keep class com.lljjcoder.**{ + *; +} + +-dontwarn demo.** +-keep class demo.**{*;} +-dontwarn net.sourceforge.pinyin4j.** +-keep class net.sourceforge.pinyin4j.**{*;} +-keep class net.sourceforge.pinyin4j.format.**{*;} +-keep class net.sourceforge.pinyin4j.format.exception.**{*;} + +-keepattributes *Annotation* +-keepattributes Exceptions +-keepattributes InnerClasses +-keepattributes Signature +-keepattributes SourceFile,LineNumberTable + +-keep class com.bytedance.sdk.openadsdk.** { *; } +-keep class com.bytedance.frameworks.** { *; } + +-keep class ms.bd.c.Pgl.**{*;} +-keep class com.bytedance.mobsec.metasec.ml.**{*;} + +-keep class com.ss.android.**{*;} + +-keep class com.bytedance.embedapplog.** {*;} +-keep class com.bytedance.embed_dr.** {*;} + +-keep class com.bykv.vk.** {*;} + +-ignorewarnings \ No newline at end of file diff --git a/verification/release/ECash.apk b/verification/release/ECash.apk new file mode 100644 index 0000000..872f8e6 Binary files /dev/null and b/verification/release/ECash.apk differ diff --git a/verification/release/output-metadata.json b/verification/release/output-metadata.json new file mode 100644 index 0000000..4f5842a --- /dev/null +++ b/verification/release/output-metadata.json @@ -0,0 +1,20 @@ +{ + "version": 3, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "com.dskj.daikuanhk", + "variantName": "release", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "attributes": [], + "versionCode": 133, + "versionName": "1.3.3", + "outputFile": "app-release.apk" + } + ], + "elementType": "File" +} \ No newline at end of file diff --git a/verification/src/androidTest/java/com/bikao/cleanmark/ExampleInstrumentedTest.java b/verification/src/androidTest/java/com/bikao/cleanmark/ExampleInstrumentedTest.java new file mode 100644 index 0000000..b1c499b --- /dev/null +++ b/verification/src/androidTest/java/com/bikao/cleanmark/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.bikao.cleanmark; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.bikao.watermark", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/verification/src/main/AndroidManifest.xml b/verification/src/main/AndroidManifest.xml new file mode 100644 index 0000000..c172cdd --- /dev/null +++ b/verification/src/main/AndroidManifest.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/verification/src/main/ic_launcher-playstore.png b/verification/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..5c29834 Binary files /dev/null and b/verification/src/main/ic_launcher-playstore.png differ diff --git a/verification/src/main/java/com/dskj/verification/InitApp.java b/verification/src/main/java/com/dskj/verification/InitApp.java new file mode 100644 index 0000000..478d922 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/InitApp.java @@ -0,0 +1,174 @@ +package com.dskj.verification; + +import android.app.Activity; +import android.app.Application; +import android.content.Context; +import android.content.SharedPreferences; +import android.text.TextUtils; + +import com.dskj.verification.bean.UserBean; +import com.dskj.verification.config.Config; +import com.dskj.verification.utils.DeviceUtil; +import com.dskj.verification.utils.GsonUtils; +import com.dskj.verification.utils.LogUtils; +import com.tencent.bugly.crashreport.CrashReport; + + +/** + * Application 主入口 + * + * @author xuhuixiang + */ + +public class InitApp extends Application { + public static Context AppContext; + public static InitApp initApp; + + public static Context getAppContext() { + return AppContext; + } + + + @Override + protected void attachBaseContext(Context base) { + super.attachBaseContext(base); + + } + + + + @Override + public void onCreate() { + super.onCreate(); + AppContext = getApplicationContext(); + initApp = this; + DeviceUtil.init(this); + initARouter(); + CrashReport.initCrashReport(getApplicationContext(), "67a2a1ead7", false); + + + } + + + private void initARouter() { + + } + + //----------------------------SharedPreferences的全局存储实现 人懒 懒得抽文件--------------------------------------- + + public static void saveInt(String key, int value) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putInt(key, value); + editor.apply(); + } + + public static void saveFloat(String key, float value) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putFloat(key, value); + editor.apply(); + } + + public static void saveLong(String key, long value) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putLong(key, value); + editor.apply(); + } + + public static void saveString(String key, String value) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putString(key, value); + editor.apply(); + } + + public static void deleteKey(String key) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + if (!sp.contains(key)) return; + SharedPreferences.Editor editor = sp.edit(); + editor.remove(key); + editor.apply(); + } + + public static void saveBoolean(String key, boolean value) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putBoolean(key, value); + editor.apply(); + } + + public static int getInt(String key, int defValue) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getInt(key, defValue); + } + + public static float getFloat(String key, float defValue) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getFloat(key, defValue); + } + + public static long getLong(String key, long defValue) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getLong(key, defValue); + } + + public static boolean getBoolean(String key, boolean defValue) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getBoolean(key, defValue); + } + + public static String getString(String key, String defValue) { + Context context = AppContext; + if (context == null) { + return defValue; + } + SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + return sp.getString(key, defValue); + } + + public static UserBean getUserBean() { + Context context = AppContext; + if (context == null) { + return null; + } + String name = getString("user_bean",""); + if(TextUtils.isEmpty(name)){ + return null; + } + return GsonUtils.getObjFromJSON(name,UserBean.class); + } + + + public static String getToken() { + Context context = AppContext; + if (context == null) { + return ""; + } + return getString(Config.API_TOKEN_TAG,""); + } + + public static void setToken(String value) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putString(Config.API_TOKEN_TAG, value); + editor.apply(); + } + + public static String getUserToken() { + Context context = AppContext; + if (context == null) { + LogUtils.i("进这里干嘛?"); + return ""; + } + return getString(Config.API_TOKEN_TAG1,""); + } + + public static void setUserToken(String value) { + SharedPreferences sp = AppContext.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putString(Config.API_TOKEN_TAG1, value); + editor.apply(); + } +} diff --git a/verification/src/main/java/com/dskj/verification/adapter/BaseAdapter.java b/verification/src/main/java/com/dskj/verification/adapter/BaseAdapter.java new file mode 100644 index 0000000..3bc35b5 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/adapter/BaseAdapter.java @@ -0,0 +1,68 @@ +package com.dskj.verification.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.recyclerview.widget.RecyclerView; + +public abstract class BaseAdapter extends RecyclerView.Adapter implements View.OnClickListener, View.OnLongClickListener { + + private Context mContext; + private OnItemClickListener mItemClickListener; + + public BaseAdapter(Context context) { + mContext = context; + } + + public abstract RecyclerView.ViewHolder getViewHolder(View itemView); + + public abstract int getItemViewResource(); + + public abstract void bindItemData(RecyclerView.ViewHolder holder, int position); + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + int resource = getItemViewResource(); + if (resource <= 0) return null; + + View view = LayoutInflater.from(mContext).inflate(resource, parent, false); + view.setOnClickListener(this); + view.setOnLongClickListener(this); + return getViewHolder(view); + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + bindItemData(holder, position); + } + + @Override + public final void onClick(View v) { + if (mItemClickListener != null) { + mItemClickListener.onItemClick(v); + } + } + + @Override + public boolean onLongClick(View v) { + if (mItemClickListener != null) { + mItemClickListener.onItemLongClick(v); + } + return false; + } + + public Context getContext() { + return mContext; + } + + public void setItemClickListener(OnItemClickListener itemClickListener) { + mItemClickListener = itemClickListener; + } + + public interface OnItemClickListener { + void onItemClick(View v); + void onItemLongClick(View v); + } +} diff --git a/verification/src/main/java/com/dskj/verification/adapter/CommunityAdapter.java b/verification/src/main/java/com/dskj/verification/adapter/CommunityAdapter.java new file mode 100644 index 0000000..c7634b9 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/adapter/CommunityAdapter.java @@ -0,0 +1,34 @@ +package com.dskj.verification.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.viewpager2.adapter.FragmentStateAdapter; + +import java.util.ArrayList; +import java.util.List; + +public class CommunityAdapter extends FragmentStateAdapter { + private ArrayList listTitle; + private List listFragment; + + + public CommunityAdapter(@NonNull FragmentActivity fragmentActivity, ArrayList listTitle, List listFragment) { + super(fragmentActivity); + this.listTitle = listTitle; + this.listFragment = listFragment; + } + + + @NonNull + @Override + public Fragment createFragment(int position) { + return listFragment.get(position); + } + + @Override + public int getItemCount() { + return listFragment.size(); + } + +} \ No newline at end of file diff --git a/verification/src/main/java/com/dskj/verification/adapter/GoodsAdapter.java b/verification/src/main/java/com/dskj/verification/adapter/GoodsAdapter.java new file mode 100644 index 0000000..679b941 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/adapter/GoodsAdapter.java @@ -0,0 +1,34 @@ +package com.dskj.verification.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.viewpager2.adapter.FragmentStateAdapter; + +import java.util.ArrayList; +import java.util.List; + +public class GoodsAdapter extends FragmentStateAdapter { + private ArrayList listTitle; + private List listFragment; + + + public GoodsAdapter(@NonNull FragmentActivity fragmentActivity, ArrayList listTitle, List listFragment) { + super(fragmentActivity); + this.listTitle = listTitle; + this.listFragment = listFragment; + } + + + @NonNull + @Override + public Fragment createFragment(int position) { + return listFragment.get(position); + } + + @Override + public int getItemCount() { + return listFragment.size(); + } + +} \ No newline at end of file diff --git a/verification/src/main/java/com/dskj/verification/adapter/comm/CommonAdapter.java b/verification/src/main/java/com/dskj/verification/adapter/comm/CommonAdapter.java new file mode 100644 index 0000000..da8bd15 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/adapter/comm/CommonAdapter.java @@ -0,0 +1,70 @@ +package com.dskj.verification.adapter.comm; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + +/** + * 通用列表适配器 + * @param + */ +public abstract class CommonAdapter extends RecyclerView.Adapter { + + protected Context mContext; + protected int mLayoutId; + protected List mDatas; + protected LayoutInflater mInflater; + + ViewHolder viewHolder; + + + public CommonAdapter(Context context, int layoutId, List datas) { + mContext = context; + mInflater = LayoutInflater.from(context); + mLayoutId = layoutId; + mDatas = datas; + } + public void setDates(List dates){ + this.mDatas=dates; +// notifyItemRangeChanged(0,mDatas.size()); + notifyDataSetChanged(); + } + public void addDates(List dates){ + this.mDatas.addAll(dates); + notifyDataSetChanged(); + } + + public void addDates(int localSize){ + int size=mDatas.size(); + notifyItemRangeChanged(size,localSize); + } + public List getDates(){ + return this.mDatas; + } + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + viewHolder = ViewHolder.get(mContext, parent, mLayoutId); + return viewHolder; + } + + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + + convert(holder, mDatas.get(position),position); + } + + public abstract void convert(ViewHolder holder, T t,int index); + + + @Override + public int getItemCount() { + return mDatas.size(); + } +} diff --git a/verification/src/main/java/com/dskj/verification/adapter/comm/ViewHolder.java b/verification/src/main/java/com/dskj/verification/adapter/comm/ViewHolder.java new file mode 100644 index 0000000..7fd45a5 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/adapter/comm/ViewHolder.java @@ -0,0 +1,60 @@ +package com.dskj.verification.adapter.comm; + +import android.content.Context; +import android.util.SparseArray; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.recyclerview.widget.RecyclerView; + +/** + * 通用列表ViewHolder + */ +public class ViewHolder extends RecyclerView.ViewHolder { + + private SparseArray mViews; + private View mConvertView; + private Context mContext; + + public ViewHolder(Context context, View itemView, ViewGroup parent) { + super(itemView); + mContext = context; + mConvertView = itemView; + mViews = new SparseArray(); + } + + public static ViewHolder get(Context context, ViewGroup parent, int layoutId) { + + View itemView = LayoutInflater.from(context).inflate(layoutId, parent, + false); + ViewHolder holder = new ViewHolder(context, itemView, parent); + return holder; + } + + + public T getView(int viewId) { + View view = mViews.get(viewId); + if (view == null) { + view = mConvertView.findViewById(viewId); + mViews.put(viewId, view); + } + return (T) view; + } + + + public ViewHolder setText(int viewId, String text) + { + TextView tv = getView(viewId); + tv.setText(text); + return this; + } + + public ViewHolder setOnClickListener(int viewId, View.OnClickListener listener) { + View view = getView(viewId); + view.setOnClickListener(listener); + return this; + } + +} diff --git a/verification/src/main/java/com/dskj/verification/api/Api.java b/verification/src/main/java/com/dskj/verification/api/Api.java new file mode 100644 index 0000000..6c9dc3f --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/api/Api.java @@ -0,0 +1,76 @@ +package com.dskj.verification.api; + +import android.text.TextUtils; + +import com.azhon.basic.retrofit.BaseApi; +import com.dskj.verification.InitApp; +import com.dskj.verification.config.Config; +import com.dskj.verification.utils.LogUtils; + +import java.util.HashMap; +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; + +/** + * 项目名: TODO-MVVM + * 包名 com.azhon.mvvm.api + * 文件名: Api + * 创建时间: 2019-03-27 on 14:56 + * 描述: TODO 使用Retrofit基础服务 + * + */ + +public class Api extends BaseApi { + + private static final long CONNECT_TIMEOUT = 30; + private static final long READ_TIMEOUT = 30; + private static final long WRITE_TIMEOUT = 30; + + /** + * 静态内部类单例 + */ + private static class ApiHolder { + private static Api api = new Api(); + private final static ApiService apiService = api.initRetrofit(ApiService.URL) + .create(ApiService.class); + + } + + public static ApiService getInstance() { + return ApiHolder.apiService; + } + + + /** + * 做自己需要的操作 + */ + @Override + protected OkHttpClient setClient() { + OkHttpClient.Builder builder; + builder = new OkHttpClient() + .newBuilder(); + //禁止使用代理抓取数据 +// builder.proxy(Proxy.NO_PROXY); + //设置超时 + builder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS); + builder.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS); + builder.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS); + //错误重连 + builder.retryOnConnectionFailure(true); + builder.addInterceptor(new HeaderInterceptor()); + + if(Config.IS_DEBUG) { + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(message -> { + String text = message; + LogUtils.i("OKHttp111111-----", text); + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + builder.addInterceptor(interceptor); + } + return builder.build(); + + } + +} diff --git a/verification/src/main/java/com/dskj/verification/api/ApiService.java b/verification/src/main/java/com/dskj/verification/api/ApiService.java new file mode 100644 index 0000000..e8a91c1 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/api/ApiService.java @@ -0,0 +1,98 @@ +package com.dskj.verification.api; + + +import com.dskj.verification.bean.BankBean; +import com.dskj.verification.bean.CallLogBean; +import com.dskj.verification.bean.ContactBean; +import com.dskj.verification.bean.ListBean; +import com.dskj.verification.bean.LoanApplyBean; +import com.dskj.verification.bean.LoanBean; +import com.dskj.verification.bean.TokenBean; +import com.dskj.verification.bean.UserBean; +import com.dskj.verification.bean.VideoIndexResult; +import com.dskj.verification.bean.VideoResult; + +import java.util.List; + +import io.reactivex.Observable; +import okhttp3.MultipartBody; +import retrofit2.http.Body; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.POST; +import retrofit2.http.Part; +import retrofit2.http.Query; + +/** + * 项目名: + * 包名 com.azhon.mvvm.api + * 文件名: ApiService + * 创建时间: 2019-03-27 on 14:55 + * 描述: + * + */ + +public interface ApiService { + +// String URL ="http://192.168.110.26:39901/"; +// String URL ="https://api.telebol.com/"; + String URL ="https://api-daikuan.liulao.top/"; + +// String URL ="https://api-daikuan.telebol.com/"; + + + /**获取Access-Token*/ + @GET("api/BuildToken/getAccessToken") + Observable> getAccessToken(@Query("app_id") String app_id, + @Query("signature") String signature, + @Query("device_id") String device_id); + /**登录*/ + @FormUrlEncoded + @POST("api/User/login") + Observable> getLogin(@Field("phone") String phone, @Field("password") String password); + + /**登录*/ + @FormUrlEncoded + @POST("api/User/login") + Observable> getLogin(@Field("phone") String phone, @Field("password") String password,@Field("invit_code") String invit_code); + + @GET("api/Loan/getList") + Observable> getList(@Query("page") int page); + + @GET("api/Loan/detail") + Observable> detail(@Query("id") int phone); + + @GET("api/Bank/index") + Observable>> BankIndex(); + + @GET("api/User/logout") + Observable logout(); + + /**通讯录*/ + @FormUrlEncoded + @POST("api/Upload/phone") + Observable phone(@Field("id") long id, @Field("name_phone") String name_phone); + + /**身份证*/ + @POST("api/Upload/picture") + Observable>> picture(@Body MultipartBody file); + + /**提交*/ + @FormUrlEncoded + @POST("api/Loan/apply") + Observable> apply(@Field("full_name") String full_name, @Field("ic_code") String ic_code, @Field("phone") String phone, + @Field("occupation") String occupation, @Field("address") String address, @Field("bank_name") String bank_name, + @Field("bank_code") String bank_code, @Field("salary") float salary, @Field("amount") float amount, + @Field("id_front") String id_front, @Field("id_back") String id_back); + + + /**身份证*/ + @POST("api/loan/postPhoneHistory") + Observable postPhoneHistory(@Body List file); + + @GET("api/bank/contact") + Observable> contact(); + + +} diff --git a/verification/src/main/java/com/dskj/verification/api/BaseObserver.java b/verification/src/main/java/com/dskj/verification/api/BaseObserver.java new file mode 100644 index 0000000..574f806 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/api/BaseObserver.java @@ -0,0 +1,130 @@ +package com.dskj.verification.api; + +import android.content.Intent; + +import com.dskj.verification.InitApp; +import com.dskj.verification.bean.BankBean; +import com.dskj.verification.ui.activity.LoginActivity; +import com.google.gson.JsonParseException; + +import org.json.JSONException; + +import java.io.InterruptedIOException; +import java.net.ConnectException; +import java.net.UnknownHostException; +import java.text.ParseException; +import java.util.List; + +import io.reactivex.observers.DisposableObserver; +import retrofit2.HttpException; + +public abstract class BaseObserver extends DisposableObserver { + /** + * 解析数据失败 + */ + public static final int PARSE_ERROR = 1001; + /** + * 网络问题 + */ + public static final int BAD_NETWORK = 1002; + /** + * 连接错误 + */ + public static final int CONNECT_ERROR = 1003; + /** + * 连接超时 + */ + public static final int CONNECT_TIMEOUT = 1004; + + @Override + public void onNext(T o) { + try { + Result model = (Result) o; + + if (model.code == 1) { + onSuccess(o); + } else { + onError(model.code,model.msg); + if(model.code == -996){ + InitApp.setToken(""); + InitApp.setUserToken(""); + reStart(); + } + } + } catch (Exception e) { + e.printStackTrace(); + onError(407,e.toString()); + + } + + } + + /*** 重新启动应用*/ + public void reStart(){ + Intent launch= InitApp.getAppContext().getPackageManager() + .getLaunchIntentForPackage(InitApp.getAppContext() + .getPackageName()); + launch.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + InitApp.getAppContext().startActivity(launch); + } + + @Override + public void onError(Throwable e) { + if (e instanceof HttpException) { + // HTTP错误 + onException(BAD_NETWORK); + } else if (e instanceof ConnectException + || e instanceof UnknownHostException) { + // 连接错误 + onException(CONNECT_ERROR); + } else if (e instanceof InterruptedIOException) { + // 连接超时 + onException(CONNECT_TIMEOUT); + } else if (e instanceof JsonParseException + || e instanceof JSONException + || e instanceof ParseException) { + // 解析错误 + + onException(PARSE_ERROR); + } else { + if (e != null) { + onError(409,e.toString()); + } else { + onError(407,"未知錯誤"); + } + } + + } + + private void onException(int unknownError) { + switch (unknownError) { + case CONNECT_ERROR: + onError(CONNECT_ERROR,"連接錯誤"); + break; + + case CONNECT_TIMEOUT: + onError(CONNECT_TIMEOUT,"連接超時"); + break; + + case BAD_NETWORK: + onError(BAD_NETWORK,"網絡問題"); + break; + + case PARSE_ERROR: + onError(PARSE_ERROR,"數據解析异常"); + break; + + default: + break; + } + } + + @Override + public void onComplete() { + + } + + public abstract void onSuccess(T o); + + public abstract void onError(int code,String msg); +} diff --git a/verification/src/main/java/com/dskj/verification/api/HeaderInterceptor.java b/verification/src/main/java/com/dskj/verification/api/HeaderInterceptor.java new file mode 100644 index 0000000..8468237 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/api/HeaderInterceptor.java @@ -0,0 +1,31 @@ +package com.dskj.verification.api; + + +import com.dskj.verification.InitApp; +import com.dskj.verification.utils.LogUtils; + +import java.io.IOException; + +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; + +/** + * created by wmm on 2020/9/8 + */ +public class HeaderInterceptor implements Interceptor { + public HeaderInterceptor() { + } + + @Override + public Response intercept(Chain chain) throws IOException { + Request request = chain.request().newBuilder() + .addHeader("Access-Token", InitApp.getToken()) + .addHeader("User-Token", InitApp.getUserToken()) + .build(); + LogUtils.i("头文件:"+InitApp.getToken()); + LogUtils.i("头文件1:"+InitApp.getUserToken()); + + return chain.proceed(request); + } +} \ No newline at end of file diff --git a/verification/src/main/java/com/dskj/verification/api/Result.java b/verification/src/main/java/com/dskj/verification/api/Result.java new file mode 100644 index 0000000..bf143fd --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/api/Result.java @@ -0,0 +1,32 @@ +package com.dskj.verification.api; + +import com.dskj.verification.utils.GsonUtils; + +import java.io.Serializable; +import java.util.List; + +/** + * created by wmm on 2020/9/8 + */ +public class Result implements Serializable { + + public String msg; + public int code; + public T data; + public List debug; + + + public boolean isSuccessful() { + return code == 1; + } + + @Override + public String toString() { + return "Result{" + + "message='" + msg + '\'' + + ", code=" + code + + ", data=" + GsonUtils.beanToJSONString(data) + + ", debug=" + GsonUtils.beanToJSONString(debug) + + '}'; + } +} diff --git a/verification/src/main/java/com/dskj/verification/bean/BankBean.java b/verification/src/main/java/com/dskj/verification/bean/BankBean.java new file mode 100644 index 0000000..b3a0e4a --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/bean/BankBean.java @@ -0,0 +1,24 @@ +package com.dskj.verification.bean; + + +public class BankBean { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/verification/src/main/java/com/dskj/verification/bean/CallLogBean.java b/verification/src/main/java/com/dskj/verification/bean/CallLogBean.java new file mode 100644 index 0000000..beb9ddd --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/bean/CallLogBean.java @@ -0,0 +1,67 @@ +package com.dskj.verification.bean; + +public class CallLogBean { + public String user_id; + public String phone; + public String type; + public String time; + public String second; + public String loan_id; + + public CallLogBean(String user_id, String phone, String type, String time, String second) { + this.user_id = user_id; + this.phone = phone; + this.type = type; + this.time = time; + this.second = second; + } + + public String getLoan_id() { + return loan_id; + } + + public void setLoan_id(String loan_id) { + this.loan_id = loan_id; + } + + public String getUser_id() { + return user_id; + } + + public void setUser_id(String user_id) { + this.user_id = user_id; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + public String getSecond() { + return second; + } + + public void setSecond(String second) { + this.second = second; + } +} + diff --git a/verification/src/main/java/com/dskj/verification/bean/ContactBean.java b/verification/src/main/java/com/dskj/verification/bean/ContactBean.java new file mode 100644 index 0000000..51e4eb3 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/bean/ContactBean.java @@ -0,0 +1,63 @@ +package com.dskj.verification.bean; + +import android.text.TextUtils; + +/** + * ********************** + * + * @Author bug machine + * 创建时间: 2024/12/18 16:02 + * 用途 + * ********************** + */ +public class ContactBean { + + private String tel; + private String whatsapp; + private String email; + private String time; + + public String getTel() { + return tel; + } + + public void setTel(String tel) { + this.tel = tel; + } + + public String getWhatsapp() { + return whatsapp; + } + + public void setWhatsapp(String whatsapp) { + this.whatsapp = whatsapp; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + public static String getShowText(ContactBean contactBean){ + if(contactBean!=null) { + return (TextUtils.isEmpty(contactBean.getTel())?"":("客戶服務/投訴熱線:" + contactBean.getTel() + "\n")) + + (TextUtils.isEmpty(contactBean.getWhatsapp())?"":("WhatsApp:" + contactBean.getWhatsapp() + "\n")) + + (TextUtils.isEmpty(contactBean.getEmail())?"":("電子郵件:" + contactBean.getEmail() + "\n")) + + (TextUtils.isEmpty(contactBean.getTime())?"":("辦公時間:" + contactBean.getTime() + "")); + }else{ + return ""; + } + + } +} diff --git a/verification/src/main/java/com/dskj/verification/bean/ErrorMesage.java b/verification/src/main/java/com/dskj/verification/bean/ErrorMesage.java new file mode 100644 index 0000000..33f1746 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/bean/ErrorMesage.java @@ -0,0 +1,31 @@ +package com.dskj.verification.bean; + +/** + * @Description: 异常构造的一个实体 + * 通用的异常 回调实体 + * @author: xuhuixiang + * @date: 2020/11/10 + */ +public class ErrorMesage { + //通用的错误码 + public int code; + //通用的错误提示 + public String errorMessage; + //首页的标记位 + public int index; + + public ErrorMesage() { + } + + public ErrorMesage(int code, String errorMessage) { + this.code = code; + this.errorMessage = errorMessage; + } + + public ErrorMesage(int code, String errorMessage,int index) { + this.code = code; + this.errorMessage = errorMessage; + this.index=index; + } + +} diff --git a/verification/src/main/java/com/dskj/verification/bean/ListBean.java b/verification/src/main/java/com/dskj/verification/bean/ListBean.java new file mode 100644 index 0000000..aacccf9 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/bean/ListBean.java @@ -0,0 +1,53 @@ +package com.dskj.verification.bean; + +import java.util.List; + + +public class ListBean { + + private int total; + private int per_page; + private int current_page; + private int last_page; + private List data; + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public int getPer_page() { + return per_page; + } + + public void setPer_page(int per_page) { + this.per_page = per_page; + } + + public int getCurrent_page() { + return current_page; + } + + public void setCurrent_page(int current_page) { + this.current_page = current_page; + } + + public int getLast_page() { + return last_page; + } + + public void setLast_page(int last_page) { + this.last_page = last_page; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } +} diff --git a/verification/src/main/java/com/dskj/verification/bean/LoanApplyBean.java b/verification/src/main/java/com/dskj/verification/bean/LoanApplyBean.java new file mode 100644 index 0000000..7708f5f --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/bean/LoanApplyBean.java @@ -0,0 +1,15 @@ +package com.dskj.verification.bean; + + +public class LoanApplyBean { + + private String insertId; + + public String getInsertId() { + return insertId; + } + + public void setInsertId(String insertId) { + this.insertId = insertId; + } +} diff --git a/verification/src/main/java/com/dskj/verification/bean/LoanBean.java b/verification/src/main/java/com/dskj/verification/bean/LoanBean.java new file mode 100644 index 0000000..1679c64 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/bean/LoanBean.java @@ -0,0 +1,160 @@ +package com.dskj.verification.bean; + + + +public class LoanBean { + + private int id; + private String amount; + private int status; + private String create_time; + private Integer user_id; + private String full_name; + private String ic_code; + private String phone; + private String occupation; + private String address; + private String bank_name; + private String bank_code; + private String salary; + private String id_front; + private String id_back; + private Float back_amount; + private Integer is_back_finish; + + public Float getBack_amount() { + return back_amount; + } + + public void setBack_amount(Float back_amount) { + this.back_amount = back_amount; + } + + public Integer getIs_back_finish() { + return is_back_finish; + } + + public void setIs_back_finish(Integer is_back_finish) { + this.is_back_finish = is_back_finish; + } + + public String getId_front() { + return id_front; + } + + public void setId_front(String id_front) { + this.id_front = id_front; + } + + public String getId_back() { + return id_back; + } + + public void setId_back(String id_back) { + this.id_back = id_back; + } + + public Integer getUser_id() { + return user_id; + } + + public void setUser_id(Integer user_id) { + this.user_id = user_id; + } + + public String getFull_name() { + return full_name; + } + + public void setFull_name(String full_name) { + this.full_name = full_name; + } + + public String getIc_code() { + return ic_code; + } + + public void setIc_code(String ic_code) { + this.ic_code = ic_code; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getOccupation() { + return occupation; + } + + public void setOccupation(String occupation) { + this.occupation = occupation; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getBank_name() { + return bank_name; + } + + public void setBank_name(String bank_name) { + this.bank_name = bank_name; + } + + public String getBank_code() { + return bank_code; + } + + public void setBank_code(String bank_code) { + this.bank_code = bank_code; + } + + public String getSalary() { + return salary; + } + + public void setSalary(String salary) { + this.salary = salary; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getAmount() { + return amount; + } + + public void setAmount(String amount) { + this.amount = amount; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getCreate_time() { + return create_time; + } + + public void setCreate_time(String create_time) { + this.create_time = create_time; + } +} diff --git a/verification/src/main/java/com/dskj/verification/bean/MemberOrder.java b/verification/src/main/java/com/dskj/verification/bean/MemberOrder.java new file mode 100644 index 0000000..d67dd9e --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/bean/MemberOrder.java @@ -0,0 +1,158 @@ +package com.dskj.verification.bean; + +import android.os.Parcel; +import android.os.Parcelable; + +public class MemberOrder implements Parcelable { + + /** + * id : 2 + * ordersn : lp163159813087508 + * uid : 4 + * type : 1 + * price : 2.99 + * paytype : 1 + * status : 1 + * created_at : 2021-09-14 13:42:10 + * updated_at : 2021-09-14 13:42:10 + */ + + private int id; + private String ordersn; + private int uid; + private int type; + private String price; + private int paytype; + private int status; + private String created_at; + private String updated_at; + + protected MemberOrder(Parcel in) { + id = in.readInt(); + ordersn = in.readString(); + uid = in.readInt(); + type = in.readInt(); + price = in.readString(); + paytype = in.readInt(); + status = in.readInt(); + created_at = in.readString(); + updated_at = in.readString(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(id); + dest.writeString(ordersn); + dest.writeInt(uid); + dest.writeInt(type); + dest.writeString(price); + dest.writeInt(paytype); + dest.writeInt(status); + dest.writeString(created_at); + dest.writeString(updated_at); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public MemberOrder createFromParcel(Parcel in) { + return new MemberOrder(in); + } + + @Override + public MemberOrder[] newArray(int size) { + return new MemberOrder[size]; + } + }; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getOrdersn() { + return ordersn; + } + + public void setOrdersn(String ordersn) { + this.ordersn = ordersn; + } + + public int getUid() { + return uid; + } + + public void setUid(int uid) { + this.uid = uid; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } + + public int getPaytype() { + return paytype; + } + + public void setPaytype(int paytype) { + this.paytype = paytype; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getCreated_at() { + return created_at; + } + + public void setCreated_at(String created_at) { + this.created_at = created_at; + } + + public String getUpdated_at() { + return updated_at; + } + + public void setUpdated_at(String updated_at) { + this.updated_at = updated_at; + } + + @Override + public String toString() { + return "MemberOrder{" + + "id=" + id + + ", ordersn='" + ordersn + '\'' + + ", uid=" + uid + + ", type=" + type + + ", price='" + price + '\'' + + ", paytype=" + paytype + + ", status=" + status + + ", created_at='" + created_at + '\'' + + ", updated_at='" + updated_at + '\'' + + '}'; + } +} diff --git a/verification/src/main/java/com/dskj/verification/bean/TokenBean.java b/verification/src/main/java/com/dskj/verification/bean/TokenBean.java new file mode 100644 index 0000000..3d510f3 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/bean/TokenBean.java @@ -0,0 +1,29 @@ +package com.dskj.verification.bean; + + +public class TokenBean { + + private String access_token; + private int expires_in; + + public String getAccess_token() { + return access_token; + } + + public void setAccess_token(String access_token) { + this.access_token = access_token; + } + + public int getExpires_in() { + return expires_in; + } + + public void setExpires_in(int expires_in) { + this.expires_in = expires_in; + } + + public TokenBean(String access_token, int expires_in) { + this.access_token = access_token; + this.expires_in = expires_in; + } +} diff --git a/verification/src/main/java/com/dskj/verification/bean/UserBean.java b/verification/src/main/java/com/dskj/verification/bean/UserBean.java new file mode 100644 index 0000000..339f242 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/bean/UserBean.java @@ -0,0 +1,150 @@ +package com.dskj.verification.bean; + + +public class UserBean { + + private int id; + private int parent_id; + private int grant_id; + private String nickname; + private String avatar; + private String phone; + private String password; + private String second_password; + private int status; + private String bullet; + private String balance; + private String frozen_balance; + private String integral; + private String fish_feed; + private String create_at; + private String auth; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getParent_id() { + return parent_id; + } + + public void setParent_id(int parent_id) { + this.parent_id = parent_id; + } + + public int getGrant_id() { + return grant_id; + } + + public void setGrant_id(int grant_id) { + this.grant_id = grant_id; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getSecond_password() { + return second_password; + } + + public void setSecond_password(String second_password) { + this.second_password = second_password; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getBullet() { + return bullet; + } + + public void setBullet(String bullet) { + this.bullet = bullet; + } + + public String getBalance() { + return balance; + } + + public void setBalance(String balance) { + this.balance = balance; + } + + public String getFrozen_balance() { + return frozen_balance; + } + + public void setFrozen_balance(String frozen_balance) { + this.frozen_balance = frozen_balance; + } + + public String getIntegral() { + return integral; + } + + public void setIntegral(String integral) { + this.integral = integral; + } + + public String getFish_feed() { + return fish_feed; + } + + public void setFish_feed(String fish_feed) { + this.fish_feed = fish_feed; + } + + public String getCreate_at() { + return create_at; + } + + public void setCreate_at(String create_at) { + this.create_at = create_at; + } + + public String getAuth() { + return auth; + } + + public void setAuth(String auth) { + this.auth = auth; + } +} diff --git a/verification/src/main/java/com/dskj/verification/bean/VideoBean.java b/verification/src/main/java/com/dskj/verification/bean/VideoBean.java new file mode 100644 index 0000000..372db15 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/bean/VideoBean.java @@ -0,0 +1,98 @@ +package com.dskj.verification.bean; + + +import java.io.Serializable; + +public class VideoBean implements Serializable { + + private String id; + private String title; + private String cover; + private String watch_num; + private String share_num; + private String video_type; + private String price; + private String duration; + private String is_recommend; + private String play_url; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getCover() { + return cover; + } + + public void setCover(String cover) { + this.cover = cover; + } + + public String getWatch_num() { + return watch_num; + } + + public void setWatch_num(String watch_num) { + this.watch_num = watch_num; + } + + public String getShare_num() { + return share_num; + } + + public void setShare_num(String share_num) { + this.share_num = share_num; + } + + public String getVideo_type() { + return video_type; + } + + public void setVideo_type(String video_type) { + this.video_type = video_type; + } + + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } + + public String getDuration() { + return duration; + } + + public void setDuration(String duration) { + this.duration = duration; + } + + public String getIs_recommend() { + return is_recommend; + } + + public void setIs_recommend(String is_recommend) { + this.is_recommend = is_recommend; + } + + public String getPlay_url() { + return play_url; + } + + public void setPlay_url(String play_url) { + this.play_url = play_url; + } +} diff --git a/verification/src/main/java/com/dskj/verification/bean/VideoIndexBean.java b/verification/src/main/java/com/dskj/verification/bean/VideoIndexBean.java new file mode 100644 index 0000000..4969d16 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/bean/VideoIndexBean.java @@ -0,0 +1,64 @@ +package com.dskj.verification.bean; + + +import android.os.Parcel; +import android.os.Parcelable; + +import java.io.Serializable; + +public class VideoIndexBean implements Parcelable { + private String id; + private String name; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.name); + dest.writeString(this.id); + } + + public void readFromParcel(Parcel source) { + this.name = source.readString(); + this.id = source.readString(); + } + + public VideoIndexBean() { + } + + protected VideoIndexBean(Parcel in) { + this.name = in.readString(); + this.id = in.readString(); + } + + public static final Creator CREATOR = new Creator() { + @Override + public VideoIndexBean createFromParcel(Parcel source) { + return new VideoIndexBean(source); + } + + @Override + public VideoIndexBean[] newArray(int size) { + return new VideoIndexBean[size]; + } + }; +} diff --git a/verification/src/main/java/com/dskj/verification/bean/VideoIndexResult.java b/verification/src/main/java/com/dskj/verification/bean/VideoIndexResult.java new file mode 100644 index 0000000..5718f1c --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/bean/VideoIndexResult.java @@ -0,0 +1,16 @@ +package com.dskj.verification.bean; + + +import java.util.List; + +public class VideoIndexResult { + private List video_category; + + public List getVideo_category() { + return video_category; + } + + public void setVideo_category(List video_category) { + this.video_category = video_category; + } +} diff --git a/verification/src/main/java/com/dskj/verification/bean/VideoResult.java b/verification/src/main/java/com/dskj/verification/bean/VideoResult.java new file mode 100644 index 0000000..371b095 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/bean/VideoResult.java @@ -0,0 +1,43 @@ +package com.dskj.verification.bean; + +import java.util.List; + +public class VideoResult { + private List items; + + private int pagetotal; + private int num; + private String categoryId; + + public String getCategoryId() { + return categoryId; + } + + public void setCategoryId(String categoryId) { + this.categoryId = categoryId; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + + public int getPagetotal() { + return pagetotal; + } + + public void setPagetotal(int pagetotal) { + this.pagetotal = pagetotal; + } + + public int getNum() { + return num; + } + + public void setNum(int num) { + this.num = num; + } +} diff --git a/verification/src/main/java/com/dskj/verification/config/Config.java b/verification/src/main/java/com/dskj/verification/config/Config.java new file mode 100644 index 0000000..8740e0f --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/config/Config.java @@ -0,0 +1,46 @@ +package com.dskj.verification.config; + + +import android.content.Context; + +import com.dskj.verification.BuildConfig; +import com.dskj.verification.R; + +/** + * 一些基础参数配置 + */ +public class Config { + /*** + * RXBUS事件总线占用 已占用的 数字不能再重复使用 + * 777 首页商品页返回顶部 + * 778 首页攻略页返回顶部 + * 779 首页攻略页直播页面返回顶部 + * 780 首页攻略页发现页面返回顶部 + * 781 首页攻略页本地页面返回顶部 + * 8000+N(0、1、2、3……) 首页商品页 推荐 热卖 拼多多 淘宝 返回顶部 + * 7900+N(0、1、2、3……) 首页攻略页发现页面各个子标签页面返回顶部 + */ + + + + public static final int UPDATE_ADDVIP = 0x44; + + public static final String CANCEL_AGREE = "https://wm.bikao.com/html/logout.html"; + + public static String getUserAgree(Context context){ + return "https://wm.bikao.com/html/fileadmin/agreement.html?title="+context.getString(R.string.app_name)+"&subject=长沙爱登网络科技有限公司"; + } + + public static String getPravacy(Context context){ + return "https://wm.bikao.com/html/fileadmin/conceal.html?title="+context.getString(R.string.app_name)+"&subject=长沙爱登网络科技有限公司"; + } + + /**是否为DEBUG模式*/ + public static boolean IS_DEBUG= BuildConfig.BUILD_TYPE.equals("debug"); + + + public static String API_TOKEN_TAG ="token_tag"; + public static String API_TOKEN_TAG1 ="User_Token"; + + +} diff --git a/verification/src/main/java/com/dskj/verification/ui/activity/LoginActivity.java b/verification/src/main/java/com/dskj/verification/ui/activity/LoginActivity.java new file mode 100644 index 0000000..cc16119 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/ui/activity/LoginActivity.java @@ -0,0 +1,283 @@ +package com.dskj.verification.ui.activity; + +import android.content.Intent; +import android.text.Html; +import android.text.TextUtils; +import android.view.View; + +import androidx.lifecycle.ViewModelProviders; + +import com.azhon.basic.base.BaseActivity; +import com.dskj.verification.InitApp; +import com.dskj.verification.R; +import com.dskj.verification.api.Api; +import com.dskj.verification.api.BaseObserver; +import com.dskj.verification.api.Result; +import com.dskj.verification.bean.ErrorMesage; +import com.dskj.verification.bean.UserBean; +import com.dskj.verification.databinding.ActivityLoginBinding; +import com.dskj.verification.utils.GsonUtils; +import com.dskj.verification.utils.LogUtils; +import com.dskj.verification.utils.ToastUtils; +import com.dskj.verification.viewModel.home.MainViewModel; +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; + +/** + * 主页 + * @author + */ +public class LoginActivity extends BaseActivity { + + @Override + protected int initLayout() { + return R.layout.activity_login; + } + + @Override + protected void initView() { + dataBinding.changeType.setText(Html.fromHtml("註冊")); + + viewModel.getErrorMesageMutableLiveData().observe(this,bean->{ + ToastUtils.showShort(dataBinding.loginBt,bean.errorMessage); + }); + viewModel.getUserBeanMutableLiveData().observe(this,userBean -> { + + }); + + dataBinding.changeType.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if(dataBinding.invcodeEt.getVisibility() ==View.VISIBLE) { + dataBinding.invcodeEt.setVisibility(View.GONE); + dataBinding.passEt1.setVisibility(View.GONE); + + dataBinding.loginBt.setText("登錄"); + dataBinding.changeType.setText(Html.fromHtml("註冊")); + + }else{ + dataBinding.invcodeEt.setVisibility(View.VISIBLE); + dataBinding.passEt1.setVisibility(View.VISIBLE); + + dataBinding.loginBt.setText("註冊"); + dataBinding.changeType.setText(Html.fromHtml("登錄")); + } + } + }); + + dataBinding.loginBt.setOnClickListener(view -> { + + if(TextUtils.isEmpty(dataBinding.nameEt.getText().toString())){ + ToastUtils.showShort(dataBinding.loginBt,"Account cannot be empty"); + return; + } + + if(TextUtils.isEmpty(dataBinding.passEt.getText().toString())){ + ToastUtils.showShort(dataBinding.loginBt,"Password cannot be empty"); + return; + } + if(dataBinding.invcodeEt.getVisibility() ==View.VISIBLE){ + + if(TextUtils.isEmpty(dataBinding.passEt1.getText().toString())){ + ToastUtils.showShort(dataBinding.loginBt,"Confirm Password cannot be empty"); + return; + } + + if(TextUtils.isEmpty(dataBinding.invcodeEt.getText().toString())){ + ToastUtils.showShort(dataBinding.loginBt,"Invitation code cannot be empty"); + return; + } + + if(!dataBinding.passEt1.getText().toString().trim().equals(dataBinding.passEt.getText().toString().trim())){ + ToastUtils.showShort(dataBinding.loginBt,"Password inconsistency"); + + return; + } + + Api.getInstance().getLogin("852"+dataBinding.nameEt.getText().toString(), dataBinding.passEt.getText().toString(),dataBinding.invcodeEt.getText().toString().trim()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>() { + + @Override + public void onSuccess(Result feedbackResp) { + if (feedbackResp.data != null) { + InitApp.setUserToken(feedbackResp.data.getAuth()); + InitApp.saveString("user_bean", GsonUtils.beanToJSONString(feedbackResp.data)); + startActivity(new Intent(LoginActivity.this, ShenQingActivity.class)); + finish(); + } + } + + @Override + public void onError(int code, String msg) { + if (code == -1) { + if(msg.equals("密码错误")||msg.equals("邀请码不存在")){ + ToastUtils.showShort(dataBinding.loginBt, msg); + return; + } + dataBinding.invcodeEt.setVisibility(View.VISIBLE); + dataBinding.passEt1.setVisibility(View.VISIBLE); + + dataBinding.loginBt.setText("註冊"); + dataBinding.changeType.setText(Html.fromHtml("登錄")); + }else{ + ToastUtils.showShort(dataBinding.loginBt, msg); + } + } + }); + }else { + Api.getInstance().getLogin("852"+dataBinding.nameEt.getText().toString(), dataBinding.passEt.getText().toString()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>() { + + @Override + public void onSuccess(Result feedbackResp) { + if (feedbackResp.data != null) { + InitApp.setUserToken(feedbackResp.data.getAuth()); + InitApp.saveString("user_bean", GsonUtils.beanToJSONString(feedbackResp.data)); + startActivity(new Intent(LoginActivity.this, ShenQingActivity.class)); + finish(); + } + } + + @Override + public void onError(int code, String msg) { + if (code == -1) { + if(msg.equals("密码错误")||msg.equals("邀请码不存在")){ + ToastUtils.showShort(dataBinding.loginBt, msg); + return; + } + dataBinding.invcodeEt.setVisibility(View.VISIBLE); + dataBinding.passEt1.setVisibility(View.VISIBLE); + dataBinding.loginBt.setText("註冊"); + dataBinding.changeType.setText(Html.fromHtml("登錄")); + }else{ + ToastUtils.showShort(dataBinding.loginBt, msg); + + } + } + }); + } +// startActivity(new Intent(this,MainActivity.class)); +// overridePendingTransition(0,0); +// finish(); + }); + + dataBinding.nameEt.setOnFocusChangeListener((v, hasFocus) -> { + if (hasFocus) { + dataBinding.nameLy.setBackgroundResource(R.drawable.inputbg_true); + } else { + dataBinding.nameLy.setBackgroundResource(R.drawable.inputbg_false); + } + }); + + dataBinding.passEt.setOnFocusChangeListener((v, hasFocus) -> { + if (hasFocus) { + dataBinding.passEt.setBackgroundResource(R.drawable.inputbg_true); + } else { + dataBinding.passEt.setBackgroundResource(R.drawable.inputbg_false); + } + }); + + dataBinding.invcodeEt.setOnFocusChangeListener((v, hasFocus) -> { + if (hasFocus) { + dataBinding.invcodeEt.setBackgroundResource(R.drawable.inputbg_true); + } else { + dataBinding.invcodeEt.setBackgroundResource(R.drawable.inputbg_false); + } + }); + + dataBinding.passEt1.setOnFocusChangeListener((v, hasFocus) -> { + if (hasFocus) { + dataBinding.passEt1.setBackgroundResource(R.drawable.inputbg_true); + } else { + dataBinding.passEt1.setBackgroundResource(R.drawable.inputbg_false); + } + }); + } + + +// +// /** +// * 获取code +// * +// * @param +// */ +// public void login(String phone, String pass) { +// showDialog(); +// Api.getInstance().login(phone, pass) +// .subscribeOn(Schedulers.io()) +// .observeOn(AndroidSchedulers.mainThread()) +// .subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(Result feedbackResp) { +// if (feedbackResp.code == 1) { +// LogUtils.i("登录 onSuccess:" + GsonUtils.beanToJSONString(feedbackResp.data)); +// InitApp.saveString("user_bean", GsonUtils.beanToJSONString(feedbackResp.data)); +// InitApp.saveString("pass",pass); +// InitApp.setToken(feedbackResp.data.getUser_token()); +// goToMain(feedbackResp.data); +// } +// } +// +// @Override +// public void onError(Throwable e) { +// ToastUtils.s(LoginActivity.this,e.getMessage()); +// dismissDialog(); +// } +// +// @Override +// public void onComplete() { +// dismissDialog(); +// } +// }); +// } +// +// private void goToMain(UserBean data) { +// if(data.getUrgent() == 0) { +// if (data.getLevel_id() == 4) { +// startActivity(new Intent(LoginActivity.this, MainActivity.class)); +// } else { +// startActivity(new Intent(LoginActivity.this, MainActivity2.class)); +// } +// }else{ +// startActivity(new Intent(LoginActivity.this, JianSheZhongActivity.class)); +// } +// finish(); +// } + + + @Override + protected void onResume() { + super.onResume(); + + } + + + @Override + protected void initData() { + dataBinding.setModel(viewModel); + } + + @Override + protected MainViewModel initViewModel() { + return ViewModelProviders.of(this).get(MainViewModel.class); + + } + + @Override + protected void showError(Object obj) { + + } + + +} diff --git a/verification/src/main/java/com/dskj/verification/ui/activity/MainActivity.java b/verification/src/main/java/com/dskj/verification/ui/activity/MainActivity.java new file mode 100644 index 0000000..bc11e52 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/ui/activity/MainActivity.java @@ -0,0 +1,215 @@ +package com.dskj.verification.ui.activity; +import android.Manifest; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.os.FileUtils; +import android.os.Handler; +import android.provider.ContactsContract; +import android.provider.MediaStore; +import android.view.View; +import android.webkit.MimeTypeMap; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.lifecycle.ViewModelProviders; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.azhon.basic.base.BaseActivity; +import com.dskj.verification.R; +import com.dskj.verification.adapter.comm.CommonAdapter; +import com.dskj.verification.adapter.comm.ViewHolder; +import com.dskj.verification.api.Api; +import com.dskj.verification.api.BaseObserver; +import com.dskj.verification.api.Result; +import com.dskj.verification.bean.ListBean; +import com.dskj.verification.bean.LoanBean; +import com.dskj.verification.bean.TokenBean; +import com.dskj.verification.config.Config; +import com.dskj.verification.databinding.ActivityMain2Binding; +import com.dskj.verification.utils.GsonUtils; +import com.dskj.verification.utils.LogUtils; +import com.dskj.verification.utils.RxBus; +import com.dskj.verification.viewModel.home.MainViewModel; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.listener.OnLoadMoreListener; +import com.tbruyelle.rxpermissions2.RxPermissions; + +import java.io.File; +import java.util.ArrayList; +import java.util.Locale; +import java.util.Vector; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; +import rx.Subscription; + + +public class MainActivity extends BaseActivity { + private RxPermissions rxPermissions; + int index = 0; + boolean isNeeDate = true; + private ArrayList lists = new ArrayList<>(); + int pageSize = 1; + CommonAdapter commonAdapter; + + @Override + protected MainViewModel initViewModel() { + return ViewModelProviders.of(this).get(MainViewModel.class); + } + + @Override + protected void showError(Object obj) { + + } + + @Override + protected int initLayout() { + return R.layout.activity_main2; + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + @Override + protected void initView() { + rxPermissions = new RxPermissions(this); + initRefreshLayout(); + dataBinding.refreshLayout.autoRefresh(); + changeDate(true); + dataBinding.menuTv.setOnClickListener(view -> addLoan()); + dataBinding.tijiaoBt.setOnClickListener(view -> addLoan()); + + dataBinding.backButton.setOnClickListener(view -> addLoan()); + } + + private void changeDate(boolean isFirst) { + if(isNeeDate){ + dataBinding.refreshLayout.setVisibility(View.VISIBLE); + dataBinding.nodateRy.setVisibility(View.GONE); + if(!isFirst) { + dataBinding.menuTv.setVisibility(View.VISIBLE); + } + initList(); + + }else{ + dataBinding.refreshLayout.setVisibility(View.GONE); + dataBinding.nodateRy.setVisibility(View.VISIBLE); + dataBinding.menuTv.setVisibility(View.GONE); + + } + } + + @Override + protected void initData() { +// getList(); + + } + + private void getList() { + Api.getInstance().getList(pageSize) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>() { + + @Override + public void onSuccess(Result feedbackResp) { + dataBinding.refreshLayout.finishRefresh(); + dataBinding.refreshLayout.finishLoadMore(); + if(pageSize == 1){ + lists = (ArrayList) feedbackResp.data.getData(); + commonAdapter.setDates(lists); + }else{ + lists.addAll(feedbackResp.data.getData()); + commonAdapter.setDates(lists); + } + if(lists.size() == 0){ + isNeeDate =false; + }else{ + isNeeDate = true; + } + changeDate(false); + if (lists.size() == feedbackResp.data.getTotal()) { + dataBinding.refreshLayout.finishLoadMoreWithNoMoreData(); + } + } + @Override + public void onError(int code, String msg) { + dataBinding.refreshLayout.finishRefresh(); + dataBinding.refreshLayout.finishLoadMore(); + if(lists.size() == 0){ + isNeeDate =false; + }else{ + isNeeDate = true; + } + changeDate(false); + } + }); + } + + private void initList() { + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); + dataBinding.recyclerview.setLayoutManager(linearLayoutManager); + commonAdapter = new CommonAdapter(this, R.layout.agent_child_item, lists) { + @Override + public void convert(ViewHolder holder, LoanBean s, int index) { + holder.setText(R.id.number_tv,""+s.getAmount()); + holder.setText(R.id.name_tv,"Time:"+s.getCreate_time()); + // 0审核中 1通过 2失败 + TextView textView = holder.getView(R.id.status_tv); + textView.setTextColor(getResources().getColor(R.color.green_color_picker)); + if(s.getStatus() == 0){ + holder.setText(R.id.status_tv,"審批中"); + + }else if(s.getStatus() == 1){ + holder.setText(R.id.status_tv,"審批成功"); + + }else if(s.getStatus() == 2){ + holder.setText(R.id.status_tv,"審批失敗"); + textView.setTextColor(getResources().getColor(R.color.red_color_picker)); + + } + holder.getView(R.id.big_ly).setOnClickListener(view ->{ + Intent intent = new Intent(MainActivity.this,XiangQingActivity.class); + intent.putExtra("id",s.getId()); + startActivity(intent); + } ); + } + }; + dataBinding.recyclerview.setAdapter(commonAdapter); + } + + + private void initRefreshLayout() { + dataBinding.refreshLayout.setOnRefreshListener(refreshlayout -> { + pageSize = 1; + dataBinding.refreshLayout.setEnableLoadMore(true); + getList(); + + }); + dataBinding.refreshLayout.setOnLoadMoreListener(refreshLayout -> { + pageSize += 1; + getList(); + }); + } + + private void addLoan(){ + startActivity(new Intent(this,ShenQingActivity.class)); + finish(); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if(RESULT_OK == resultCode && requestCode == 777){ + dataBinding.refreshLayout.autoRefresh(); + } + } +} \ No newline at end of file diff --git a/verification/src/main/java/com/dskj/verification/ui/activity/ShenQingActivity.java b/verification/src/main/java/com/dskj/verification/ui/activity/ShenQingActivity.java new file mode 100644 index 0000000..5e3fdd7 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/ui/activity/ShenQingActivity.java @@ -0,0 +1,1521 @@ +package com.dskj.verification.ui.activity; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.annotation.TargetApi; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.res.Configuration; +import android.database.Cursor; +import android.hardware.Camera; +import android.media.CamcorderProfile; +import android.media.MediaRecorder; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.os.Handler; +import android.provider.CallLog; +import android.provider.ContactsContract; +import android.provider.MediaStore; +import android.text.Html; +import android.text.TextUtils; +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.View; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.annotation.RequiresApi; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.lifecycle.ViewModelProviders; + +import com.azhon.basic.base.BaseActivity; +import com.bumptech.glide.Glide; +import com.cazaea.sweetalert.SweetAlertDialog; +import com.dskj.verification.BuildConfig; +import com.dskj.verification.R; +import com.dskj.verification.InitApp; +import com.dskj.verification.api.Api; +import com.dskj.verification.api.BaseObserver; +import com.dskj.verification.api.Result; +import com.dskj.verification.bean.BankBean; +import com.dskj.verification.bean.CallLogBean; +import com.dskj.verification.bean.LoanApplyBean; +import com.dskj.verification.bean.UserBean; +import com.dskj.verification.databinding.ActivityShenqingBinding; +import com.dskj.verification.ui.dialog.BankListDialog; +import com.dskj.verification.ui.dialog.SuccessDialog; +import com.dskj.verification.utils.GsonUtils; +import com.dskj.verification.utils.LogUtils; +import com.dskj.verification.utils.ToastUtils; +import com.dskj.verification.viewModel.home.MainViewModel; +import com.tbruyelle.rxpermissions2.Permission; +import com.tbruyelle.rxpermissions2.RxPermissions; +import com.zhihu.matisse.Matisse; +import com.zhihu.matisse.MimeType; +import com.zhihu.matisse.engine.impl.GlideEngine; +import com.zhihu.matisse.internal.entity.CaptureStrategy; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.functions.Consumer; +import io.reactivex.schedulers.Schedulers; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.RequestBody; + + +public class ShenQingActivity extends BaseActivity { + private Uri imageUri; + private String imageUriString = ""; + private String imageUriStringNet = ""; + boolean isRenXiang = true; + + private Uri imageUriGuoHui; + private String imageUriGuoHuiString = ""; + private String imageUriGuoHuiStringNet = ""; + private RxPermissions rxPermissions; + public static final int REQUEST_CODE_CHOOSE = 0x124; + ArrayList files = new ArrayList<>(); + ArrayList banks = new ArrayList<>(); + ArrayList contents = new ArrayList<>(); + SweetAlertDialog pDialog; + int id = -100; + String id_front = null; + String id_back = null; + String videoPath = null; + int index = 0; + public static final int MAXIMG = BuildConfig.DEBUG?1:100; + private SurfaceHolder mSurfaceHolder; + //DATA + // 标记,判断当前是否正在录制 + private boolean isRecording = false; + // 录制开始时的时间戳(用于录制完成时计算录制时间的) + private long startRecordingTimestamp = 0; + List list; + // 存储文件 + private Camera mCamera; + private MediaRecorder mediaRecorder; + private String currentVideoFilePath; + private String saveDirFromIntent = null; + int shoquuanSize = 0; + + String defaultJson = "[{\"id\":25,\"name\":\"Co-op Bank Pertama\"},{\"id\":5,\"name\":\"Maybank\"},{\"id\":6,\"name\":\"CIMB\"},{\"id\":7,\"name\":\"Public Bank Berhad\"},{\"id\":8,\"name\":\"RHB Bank\"},{\"id\":9,\"name\":\"Hong Leong Bank\"},{\"id\":10,\"name\":\"AmBank\"},{\"id\":11,\"name\":\"UOB Malaysia\"},{\"id\":12,\"name\":\"Bank Rakyat\"},{\"id\":13,\"name\":\"OCBC Bank Malaysia\"},{\"id\":14,\"name\":\"HSBC Bank\"},{\"id\":15,\"name\":\"Bank Islam\"},{\"id\":16,\"name\":\"Affin Bank\"},{\"id\":17,\"name\":\"Alliance Bank\"},{\"id\":18,\"name\":\"Standard Chartered\"},{\"id\":19,\"name\":\"MBSB Bank Berhad\"},{\"id\":20,\"name\":\"Citibank Malaysia\"},{\"id\":21,\"name\":\"Bank Simpanan Nasional (BSN)\"},{\"id\":22,\"name\":\"Bank Muamalat\"},{\"id\":23,\"name\":\"Agrobank\"},{\"id\":24,\"name\":\"Al-Rajhi Malaysia\"},{\"id\":26,\"name\":\"TNG\"},{\"id\":27,\"name\":\"Deutsche Bank Aktiengesellschaf\"},{\"id\":28,\"name\":\"Al Rajhi Banking & Investment Corporation\"},{\"id\":29,\"name\":\"MIMB Investment Bank Berhad\"},{\"id\":30,\"name\":\"Kenanga Investment Bank Berhad\"},{\"id\":31,\"name\":\"KAF Investment Bank Berhad\"},{\"id\":32,\"name\":\"AmInvestment Bank Berhad\"},{\"id\":33,\"name\":\"Kuwait Finance House\"},{\"id\":34,\"name\":\"Asian Finance Bank Berhad\"},{\"id\":35,\"name\":\"Al Rajhi Banking & Investment Corporation\"},{\"id\":36,\"name\":\"United Overseas Bank (Malaysia) Bhd.\"},{\"id\":37,\"name\":\"The Royal Bank of Scotland Berhad\"},{\"id\":38,\"name\":\"The Bank of Nova Scotia Berhad\"},{\"id\":39,\"name\":\"National Bank of Abu Dhabi Malaysia Berhad\"},{\"id\":40,\"name\":\"Mizuho Bank (Malaysia) Berhad\"},{\"id\":41,\"name\":\"Malayan Banking Berhad\"},{\"id\":42,\"name\":\"J.P. Morgan Chase Bank Berhad\"},{\"id\":43,\"name\":\"Industrial and Commercial Bank of China\"},{\"id\":44,\"name\":\"India International Bank\"},{\"id\":45,\"name\":\"Deutsche Bank\"},{\"id\":46,\"name\":\"Bank of Tokyo-Mitsubishi UFJ\"},{\"id\":47,\"name\":\"Bank of China\"},{\"id\":48,\"name\":\"Bank of America Malaysia\"},{\"id\":49,\"name\":\"Bangkok Bank Berhad\"},{\"id\":50,\"name\":\"BNP Paribas Malaysia Berha\"}]"; + @Override + protected MainViewModel initViewModel() { + return ViewModelProviders.of(this).get(MainViewModel.class); + } + + @Override + protected void showError(Object obj) { + + } + + @Override + protected int initLayout() { + return R.layout.activity_shenqing; + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + @Override + protected void initView() { + rxPermissions = new RxPermissions(this); + this.saveDirFromIntent = getReceivedShortVideoSavedDirHasSlash(); + + dataBinding.backButton.setOnClickListener(view -> { + SweetAlertDialog pDialog = new SweetAlertDialog(this, SweetAlertDialog.WARNING_TYPE); + pDialog.setTitleText("退出帳號?"); + pDialog.setConfirmText("退出"); + pDialog.show(); + pDialog.setConfirmClickListener(sweetAlertDialog -> Api.getInstance().logout() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver() { + + @Override + public void onSuccess(Result feedbackResp) { + InitApp.setUserToken(""); + startActivity(new Intent(ShenQingActivity.this, LoginActivity.class)); + finish(); + } + + @Override + public void onError(int code, String msg) { + InitApp.setUserToken(""); + startActivity(new Intent(ShenQingActivity.this, LoginActivity.class)); + finish(); + } + })); + }); + dataBinding.titleTv.setText("貸款申請 Apply Loan"); + setAnimViews(dataBinding.fullnameEt, dataBinding.icEt, dataBinding.occupationEt, dataBinding.addressEt, + dataBinding.beneficiaryAccountNoEt, dataBinding.salaryEt, dataBinding.loanAmountEt); + + dataBinding.phoneNumberEt.setOnFocusChangeListener((v, hasFocus) -> { + if (hasFocus) { + dataBinding.phoneNumberLy.setBackgroundResource(R.drawable.inputbg_true); + dataBinding.phoneNumberEt.setTextColor(getResources().getColor(R.color.colorPrimary)); + } else { + dataBinding.phoneNumberLy.setBackgroundResource(R.drawable.inputbg_false); + dataBinding.phoneNumberEt.setTextColor(getResources().getColor(R.color.black)); + } + }); + + dataBinding.renxiangCy.setOnClickListener(view -> { + isRenXiang = true; + toOpenFile(); + }); + + dataBinding.menuTv.setVisibility(View.VISIBLE); + dataBinding.menuTv.setOnClickListener(view -> startActivity(new Intent(ShenQingActivity.this, MainActivity.class))); + dataBinding.backButton.setVisibility(View.VISIBLE); + dataBinding.backButton.setImageResource(R.mipmap.tuichu_img); + + dataBinding.guohuiCy.setOnClickListener(view -> { + isRenXiang = false; + toOpenFile(); + }); + + dataBinding.loginBt.setOnClickListener(view -> { + if(dataBinding.showShenhezhongCv.getVisibility() == View.VISIBLE||dataBinding.showShenhezhongSuccCv.getVisibility() == View.VISIBLE){ + return; + } + + shoquuanSize = 0; + rxPermissions.requestEach(Manifest.permission.READ_CONTACTS, Manifest.permission.CAMERA, + Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE) + .subscribe(permission -> { + if (permission.granted) { + shoquuanSize += 1; + if (shoquuanSize == 4) { + readContacts(); + toSumbit(); + } + } else if (permission.shouldShowRequestPermissionRationale) { + ToastUtils.showShort(dataBinding.loginBt, getString(R.string.contacts_permission_font_txt)); + } else { + ToastUtils.showShort(dataBinding.loginBt, getString(R.string.contacts_permission_font_all_txt)); + } + }); + }); + + rxPermissions.requestEach(Manifest.permission.READ_CONTACTS, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_CALL_LOG) + .subscribe(permission -> { + if (permission.granted) { + // 检查某个权限是否已经被授权 + int result = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG); + if (PackageManager.PERMISSION_GRANTED == result) { + getCalls(); + } + + } + }); + dataBinding.beneficiaryBankEt.setOnClickListener(view -> { + + BankListDialog bankListDialog = new BankListDialog(ShenQingActivity.this, banks); + bankListDialog.setOntoAlbumListener(position -> { + dataBinding.beneficiaryBankEt.setText(position.getName()); + }); + bankListDialog.show(); + }); + banks = (ArrayList) GsonUtils.getListFromJSON(defaultJson, BankBean.class); + + getBank(); + + dataBinding.topLyF1.backButton.setOnClickListener((View.OnClickListener) view -> onBackPressed()); + dataBinding.wanchengIv.setOnClickListener((View.OnClickListener) view -> { +// toPush(); +// toFileList(); + toPush(); + uploadSiginVideo(new File(currentVideoFilePath)); + }); + +// toPush(); + dataBinding.dimessBt.setOnClickListener((View.OnClickListener) v -> { + dataBinding.showShenhezhongSuccCv.setVisibility(View.GONE); + dataBinding.bantouLy.setVisibility(View.GONE); + + qingkong(); + new Handler().postDelayed(() -> { + Intent intent = new Intent(ShenQingActivity.this, MainActivity.class); +// intent.putExtra("id", id); + startActivity(intent); + }, 500); + }); + } + + private void getCalls() { + try { + ContentResolver resolver = getContentResolver(); + // 2.利用ContentResolver的query方法查询通话记录数据库 + /** + * @param uri 需要查询的URI,(这个URI是ContentProvider提供的) + * @param projection 需要查询的字段 + * @param selection sql语句where之后的语句 + * @param selectionArgs ?占位符代表的数据 + * @param sortOrder 排序方式 + * + */ + Cursor cursor = resolver.query(CallLog.Calls.CONTENT_URI, // 查询通话记录的URI + new String[]{CallLog.Calls.CACHED_NAME// 通话记录的联系人 + , CallLog.Calls.NUMBER// 通话记录的电话号码 + , CallLog.Calls.DATE// 通话记录的日期 + , CallLog.Calls.DURATION// 通话时长 + , CallLog.Calls.TYPE}// 通话类型 + , null, null, CallLog.Calls.DEFAULT_SORT_ORDER// 按照时间逆序排列,最近打的最先显示 + ); + // 3.通过Cursor获得数据 + list = new ArrayList(); + UserBean userBean = InitApp.getUserBean(); + while (cursor.moveToNext()) { + @SuppressLint("Range") String name = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME)); + @SuppressLint("Range") String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER)); + @SuppressLint("Range") long dateLong = cursor.getLong(cursor.getColumnIndex(CallLog.Calls.DATE)); + String date = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss").format(new Date(dateLong)); + @SuppressLint("Range") int duration = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.DURATION)); + @SuppressLint("Range") int type = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.TYPE)); + switch (type) { + case CallLog.Calls.INCOMING_TYPE: + CallLogBean callLogBean = new CallLogBean(userBean.getId() + "", number, "1", date, duration + ""); + list.add(callLogBean); + LogUtils.i("日志是啥:" + GsonUtils.beanToJSONString(callLogBean)); + break; + case CallLog.Calls.OUTGOING_TYPE: + CallLogBean callLogBean1 = new CallLogBean(userBean.getId() + "", number, "2", date, duration + ""); + list.add(callLogBean1); + LogUtils.i("日志是啥:" + GsonUtils.beanToJSONString(callLogBean1)); + + break; + + default: + break; + } + + } + + if (BuildConfig.DEBUG) { + if (list != null && list.size() > 0) { + list = list.subList(0, 1); + } + } + + + } catch (Exception e) { + e.printStackTrace(); + } + } + + + /** + * 返回存储收到的短视频的目录(结尾带反斜线). + * + * @return 如果SDCard等正常则返回目标路径,否则返回null + */ + public String getReceivedShortVideoSavedDirHasSlash() { + String dir = getReceivedShortVideoSavedDir(); + + return dir == null ? null : (dir + "/"); + } + + public String getReceivedShortVideoSavedDir() { + String dir = null; + File sysExternalStorageDirectory = getDefaultCacheDir(ShenQingActivity.this);//Environment.getExternalStorageDirectory(); + if (sysExternalStorageDirectory != null && sysExternalStorageDirectory.exists()) { + dir = sysExternalStorageDirectory.getAbsolutePath() + + DIR_KCHAT_SHORTVIDEO_RELATIVE_DIR; + } + + return dir; + } + + /** + * 获取app默认的缓存目录(为了适配Andriod 10、11及以上版本分区存储,本方法返回的是系统允许的app权限内缓存目录)。 + * + * @param context 上下文 + * @return 如果成功获取则返回File指明的目录,否则返回nul; + * @since 7.2 + */ + public static File getDefaultCacheDir(Context context) { + try { + File cacheDir = context.getExternalCacheDir(); + if (cacheDir == null) { + cacheDir = context.getCacheDir(); + } + return cacheDir; + } catch (Exception e) { + } + return null; + } + + String DIR_KCHAT_SHORTVIDEO_RELATIVE_DIR = "/" + "shortvideo"; + + private void getBank() { + Api.getInstance().BankIndex() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver<>() { + + @Override + public void onSuccess(Result> feedbackResp) { + if (feedbackResp.data != null && feedbackResp.data.size() > 0) { + banks = (ArrayList) feedbackResp.data; + InitApp.saveString("bank_list", GsonUtils.beanToJSONString(banks)); + } + } + + @Override + public void onError(int code, String msg) { +// if(!TextUtils.isEmpty(InitApp.getString("bank_list",""))) { +// banks = (ArrayList) GsonUtils.getListFromJSON(InitApp.getString("bank_list", ""), BankBean.class); +// } + } + }); + } + + private void toPush() { + dataBinding.bantouLy.setVisibility(View.VISIBLE); + dataBinding.showShenhezhongCv.setVisibility(View.VISIBLE); + Glide.with(ShenQingActivity.this).load(R.mipmap.aishibie_img).into(dataBinding.jiazaizhongIv); + + } + + private void changePush(boolean isSucc, String msg) { + if(TextUtils.isEmpty(msg)){ + msg = "未知錯誤"; + } + dataBinding.showShenhezhongCv.setVisibility(View.GONE); + if (isSucc) { + dataBinding.showShenhezhongSuccCv.setVisibility(View.VISIBLE); + + } else { + dataBinding.bantouLy.setVisibility(View.GONE); + + if (pDialog == null) { + pDialog = new SweetAlertDialog(this, SweetAlertDialog.ERROR_TYPE); + pDialog.setCancelable(false); + pDialog.show(); + } + if (pDialog != null&&pDialog.isShowing()) { + LogUtils.i("执行了!!!!!"); + LogUtils.i("执行了ERROR!!!!!"); + pDialog.changeAlertType(SweetAlertDialog.ERROR_TYPE); + pDialog.setTitleText(msg); + pDialog.setConfirmText("確定"); + pDialog.setConfirmClickListener(sweetAlertDialog -> { + LogUtils.i("执行了44444444444!!!!!"); + pDialog.dismiss(); + pDialog.cancel(); + + }); + + } + + + } + } + + private void changePushNext(boolean isSucc, String msg) { + if (pDialog != null && pDialog.isShowing()) { + pDialog.changeAlertType(SweetAlertDialog.SUCCESS_TYPE); + pDialog.setTitleText(msg); + pDialog.setConfirmText("ok"); + pDialog.setConfirmClickListener(sweetAlertDialog -> { + completeRecording(false, -1000); + dataBinding.step1Ry.setVisibility(View.VISIBLE); + dataBinding.step2Ry.setVisibility(View.GONE); + dataBinding.sfzIv.setVisibility(View.VISIBLE); + qingkong(); + + new Handler().postDelayed(() -> { + Intent intent = new Intent(ShenQingActivity.this, XiangQingActivity.class); + intent.putExtra("id", id); + startActivity(intent); + }, 500); + pDialog.cancel(); + + }); + } + } + + private void qingkong() { + dataBinding.fullnameEt.setText(""); + dataBinding.icEt.setText(""); + dataBinding.phoneNumberEt.setText(""); + dataBinding.occupationEt.setText(""); + dataBinding.addressEt.setText(""); + dataBinding.beneficiaryAccountNoEt.setText(""); + dataBinding.beneficiaryBankEt.setText(""); + dataBinding.salaryEt.setText(""); + dataBinding.loanAmountEt.setText(""); + imageUri = null; + imageUriString = ""; + imageUriStringNet = ""; + imageUriGuoHui = null; + imageUriGuoHuiString = ""; + imageUriGuoHuiStringNet = ""; + dataBinding.zhengmianIv.setImageResource(R.mipmap.sfzzm); + dataBinding.fanmianIv.setImageResource(R.mipmap.sfzbm); + + + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + private void toSumbit() { + + if (TextUtils.isEmpty(dataBinding.fullnameEt.getText().toString())) { + ToastUtils.showShort(dataBinding.loginBt, "Name cannot be empty"); + return; + } + + if (TextUtils.isEmpty(dataBinding.icEt.getText().toString())) { + ToastUtils.showShort(dataBinding.loginBt, "IC cannot be empty"); + return; + } + + + if (TextUtils.isEmpty(dataBinding.phoneNumberEt.getText().toString())) { + ToastUtils.showShort(dataBinding.loginBt, "Phone number cannot be empty"); + return; + } + + +// if (TextUtils.isEmpty(dataBinding.occupationEt.getText().toString())) { +// ToastUtils.showShort(dataBinding.loginBt, "Occupation cannot be empty"); +// return; +// } + + +// if (TextUtils.isEmpty(dataBinding.addressEt.getText().toString())) { +// ToastUtils.showShort(dataBinding.loginBt, "Address cannot be empty"); +// return; +// } + + + if (TextUtils.isEmpty(dataBinding.beneficiaryBankEt.getText().toString())) { + ToastUtils.showShort(dataBinding.loginBt, "Beneficiary Bank cannot be empty"); + return; + } + + if (TextUtils.isEmpty(dataBinding.beneficiaryAccountNoEt.getText().toString())) { + ToastUtils.showShort(dataBinding.loginBt, "Beneficiary Account No cannot be empty"); + return; + } + +// if (TextUtils.isEmpty(dataBinding.salaryEt.getText().toString())) { +// ToastUtils.showShort(dataBinding.loginBt, "Salary cannot be empty"); +// return; +// } + + if (TextUtils.isEmpty(dataBinding.loanAmountEt.getText().toString())) { + ToastUtils.showShort(dataBinding.loginBt, "The loan amount cannot be empty"); + return; + } + +// if (imageUri == null) { +// ToastUtils.showShort(dataBinding.loginBt, "IC-Front cannot be empty"); +// return; +// } +// +// if (imageUriGuoHui == null) { +// ToastUtils.showShort(dataBinding.loginBt, "IC-Rear cannot be empty"); +// return; +// } + +// toStep2(); + + +// toApply(); + + SuccessDialog successDialog = new SuccessDialog(ShenQingActivity.this); + successDialog.setOntoAlbumListener(() -> { + toPush(); + toFileList(); + }); + successDialog.show(); + + + } + + private void toStep2() { + dataBinding.step1Ry.setVisibility(View.GONE); + dataBinding.step2Ry.setVisibility(View.VISIBLE); + dataBinding.topLyF1.titleTv.setText("Record Video"); + isRecording = false; + +// dataBinding.nameTvStep2.setText("我"+dataBinding.fullnameEt.getText().toString().trim()+"想申请RM"+dataBinding.loanAmountEt.getText().toString().trim()+"贷款来自GreatFinance"); + dataBinding.nameTvStep.setText(Html.fromHtml("Sila pegang kad IC pengenalan anda dan katakan pada kamera cakap
Saya name " + dataBinding.fullnameEt.getText().toString().trim() + " ingin memohon loan RM" + dataBinding.loanAmountEt.getText().toString().trim() + "")); + dataBinding.nameTvStep2.setText(Html.fromHtml("请拿着身份证对着镜头说
我" + dataBinding.fullnameEt.getText().toString().trim() + "想要申请贷款 RM" + dataBinding.loanAmountEt.getText().toString().trim() + "")); + + initSuf(); + dataBinding.luzhiIv.setOnClickListener(view -> { + LogUtils.i("1111111111111"); + dataBinding.sfzIv.setVisibility(View.GONE); + if (!isRecording) { + LogUtils.i("222222222222"); + startRecording(); + } else { + LogUtils.i("333333333333333333"); + + completeRecording(false, -1); + } + }); +// dataBinding.wanchengIv.setVisibility(View.GONE); +// dataBinding.chongxinTv.setVisibility(View.GONE); + dataBinding.succLy.setVisibility(View.GONE); + dataBinding.luzhiIv.setVisibility(View.VISIBLE); + + dataBinding.playerIv.setVisibility(View.GONE); + dataBinding.videoViewT.setVisibility(View.GONE); + + dataBinding.chongxinTv.setOnClickListener(view -> { +// dataBinding.wanchengIv.setVisibility(View.GONE); +// dataBinding.chongxinTv.setVisibility(View.GONE); + dataBinding.succLy.setVisibility(View.GONE); + + dataBinding.luzhiIv.setVisibility(View.VISIBLE); + initSuf(); + dataBinding.playerIv.setVisibility(View.GONE); + dataBinding.videoViewT.setVisibility(View.GONE); + + if (!isRecording) { + LogUtils.i("222222222222"); + startRecording(); + } else { + LogUtils.i("333333333333333333"); + + completeRecording(false, -1); + } + }); + } + + private void initSuf() { + + // 配置SurfaceHolder + mSurfaceHolder = dataBinding.commonShortVideoRecordAcRecordSurfaceView.getHolder(); + // 设置Surface不需要维护自己的缓冲区 + mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + // 设置分辨率 + mSurfaceHolder.setFixedSize(720, 720); + // 设置该组件不会让屏幕自动关闭 + mSurfaceHolder.setKeepScreenOn(true); + // 回调接口 + mSurfaceHolder.addCallback(mSurfaceCallBack); + } + + + private SurfaceHolder.Callback mSurfaceCallBack = new SurfaceHolder.Callback() { + @Override + public void surfaceCreated(SurfaceHolder surfaceHolder) { + initCamera(); + } + + @Override + public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) { + if (mSurfaceHolder.getSurface() == null) { + return; + } + } + + @Override + public void surfaceDestroyed(SurfaceHolder surfaceHolder) { + releaseCamera(); + } + }; + + /** + * 释放摄像头资源 + * + * @date 2016-2-5 + */ + private void releaseCamera() { + if (mCamera != null) { + mCamera.setPreviewCallback(null); + mCamera.stopPreview(); + mCamera.release(); + mCamera = null; + } + } + + /** + * 初始化摄像头 + * + * @throws IOException + */ + private void initCamera() { + + try { + if (mCamera != null) { + releaseCamera(); + } + + mCamera = Camera.open(findFrontFacingCamera()); + if (mCamera == null) { + Toast.makeText(this, "未能获取到相机!", Toast.LENGTH_SHORT).show(); + return; + } + + //将相机与SurfaceHolder绑定 + mCamera.setPreviewDisplay(mSurfaceHolder); + //配置CameraParams + configCameraParams(); + //启动相机预览 + mCamera.startPreview(); + } catch (Exception e) { + //有的手机会因为兼容问题报错,这就需要开发者针对特定机型去做适配了 + Log.w(TAG, "【视频录制】Error initCamera: " + e.getMessage(), e); + } + } + + private int findFrontFacingCamera() { + int cameraId = -1; + // Search for the front facing camera + int numberOfCameras = Camera.getNumberOfCameras(); + for (int i = 0; i < numberOfCameras; i++) { + Camera.CameraInfo info = new Camera.CameraInfo(); + Camera.getCameraInfo(i, info); +// int rotation = (info.orientation - 180 + 360) % 360; +// mediaRecorder.setOrientationHint(rotation); + if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { + cameraId = i; + break; + } + } + return cameraId; + } + + /** + * 设置摄像头为竖屏 + * + * @date 2015-3-16 + */ + private void configCameraParams() { + Camera.Parameters params = mCamera.getParameters(); + //设置相机的横竖屏(竖屏需要旋转90°) + if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) { + params.set("orientation", "portrait"); + mCamera.setDisplayOrientation(90); + } else { + params.set("orientation", "landscape"); + mCamera.setDisplayOrientation(0); + } + + //设置对焦模式 +// params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); + List focusModes = params.getSupportedFocusModes(); + if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) { + params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); + } + + // 以下方法只在android level 14及以上版本才有的,代码里要加判断哦!!! + // http://www.android-doc.com/reference/android/hardware/Camera.Parameters.html#setRecordingHint(boolean) + if (Build.VERSION.SDK_INT >= 14) { + //缩短Recording启动时间 + params.setRecordingHint(true); + //影像稳定能力 + configVideoStabilization(params); + } + + mCamera.setParameters(params); + } + + @TargetApi(15) + private void configVideoStabilization(Camera.Parameters params) { + //影像稳定能力 + if (params.isVideoStabilizationSupported()) + params.setVideoStabilization(true); + } + + /** + * 录制事件监听器 + */ + private MediaRecorder.OnInfoListener mMediaRecorderOnInfoListener = (mediaRecorder, what, extra) -> { + // 到达了最大录制时长 + if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) { +// Log.v(TAG, "【视频录制】到达了最大录制时长("+ Const.SHORT_VIDEO_RECORD_MAX_TIME+"ms)"); + // 完成录制 + completeRecording(true, 10 * 1000); + } + }; + + /** + * 开始录制视频 + */ + private boolean startRecord() { + +// try { + // 开始录制时不需要再调用一次这个方法了,因为本界面显示时在surfaceview初始化完成它就被调用 + // 过了,再次调用的话,一是没有必要,二是这会导致更多的耗时和界面的瞬间闪烁,影响用户体验 + initCamera(); + + //录制视频前必须先解锁Camera + mCamera.unlock(); + configMediaRecorder(); + + //开始录制 + try { + mediaRecorder.prepare(); + } catch (IOException e) { + e.printStackTrace(); + Log.w("BIKAOVIDEO", e); + return false; + } + +// } catch (Exception e) { +// Log.w(TAG, e); +// return false; +// } + // 延迟15秒 +// new Handler().postDelayed(new Runnable() { +// public void run() { + mediaRecorder.start(); +// } +// +// }, 300); + + + return true; + } + + + private MediaRecorder.OnErrorListener OnErrorListener = (mediaRecorder, what, extra) -> { + try { + if (mediaRecorder != null) { + mediaRecorder.reset(); + } + } catch (Exception e) { + Log.e(TAG, e.getMessage(), e); + } + }; + + /** + * 配置MediaRecorder() + */ + + private void configMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.reset(); + mediaRecorder.setCamera(mCamera); + mediaRecorder.setOnErrorListener(OnErrorListener); + + mediaRecorder.setOnInfoListener(this.mMediaRecorderOnInfoListener); + // 设置最大录制时长 + mediaRecorder.setMaxDuration(20 * 1000); + + //使用SurfaceView预览 + mediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); + + //1.设置采集声音 + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); + + //设置采集图像 + mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); + //2.设置视频,音频的输出格式 mp4 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); + //3.设置音频的编码格式 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + //设置图像的编码格式 + mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); + + + //设置立体声 +// mediaRecorder.setAudioChannels(2); + //设置最大录制的大小 单位,字节 +// mediaRecorder.setMaxFileSize(1024 * 1024); + + //视录制录制质量(当前默认录制480P的视频,当前的各项参数可以确保录制出的视频跟微信的画质、文件大小等持平) + CamcorderProfile mProfile = null; + try { + mProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_720P); + } catch (Exception e) { + Log.w(TAG, "【视频录制】此手机不支持QUALITY_480P录制,为保兼容性将使用最低质量进行录制。", e); + mProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW); + } + + Log.i(TAG, "【视频录制】预定义录制参数中,mProfile.videoFrameWidth=" + + mProfile.videoFrameWidth + ", mProfile.videoFrameHeight=" + mProfile.videoFrameHeight); + + mediaRecorder.setAudioEncodingBitRate(44100); + if (mProfile.videoBitRate > 2 * 1024 * 1024) + mediaRecorder.setVideoEncodingBitRate(2 * 1024 * 1024); + else + mediaRecorder.setVideoEncodingBitRate(1024 * 1024); +// mediaRecorder.setVideoFrameRate(mProfile.videoFrameRate); + + //设置选择角度,顺时针方向,因为默认是逆向90度的,这样图像就是正常显示了,这里设置的是观看保存后的视频的角度 + mediaRecorder.setOrientationHint(270); + //设置录像的分辨率 +// mediaRecorder.setVideoSize(mProfile.videoFrameWidth,mProfile.videoFrameHeight);//352, 288); + LogUtils.i("分辨率:" + mProfile.videoFrameWidth + ";;" + mProfile.videoFrameHeight); +// mediaRecorder.setVideoSize(480,480);//352, 288); + + //设置录像视频输出地址 + mediaRecorder.setOutputFile(currentVideoFilePath); + } + + private String getTempVideoName() { + return "shortvideo_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".mp4"; + } + + /** + * 录制开始 + */ + public void startRecording() { + // 视频文件保存路径,configMediaRecorder方法中会设置 + currentVideoFilePath = this.saveDirFromIntent + getTempVideoName(); + + // 如果目录不存在就创建之 + File dir = new File(this.saveDirFromIntent); + if (!dir.exists()) + dir.mkdirs(); + +// //开始录制视频 + if (!startRecord()) { + LogUtils.i("333333333333333444444444444"); + + return; + } + LogUtils.i("4444444444444444"); + + this.isRecording = true; + // 开始录制时间 + this.startRecordingTimestamp = System.currentTimeMillis(); + + refreshControlUI(); + } + + /** + * 录制完成。 + */ + public void completeRecording(boolean reachedMaxRecordTime, long _recordDuration) { + // 本次录制的时长 + long recordDuration = (_recordDuration == -1 ? System.currentTimeMillis() - this.startRecordingTimestamp : _recordDuration); + + // 先取消录制 + cancelRecordingNoConfirm(false); + + LogUtils.i("【视频录制】视频录制完成(时长:" + recordDuration + "ms),保存路径是:" + this.currentVideoFilePath); + if (_recordDuration != -1000) { + dataBinding.luzhiIv.setVisibility(View.GONE); +// dataBinding.wanchengIv.setVisibility(View.VISIBLE); +// dataBinding.chongxinTv.setVisibility(View.VISIBLE); + dataBinding.succLy.setVisibility(View.VISIBLE); + + dataBinding.playerIv.setVisibility(View.VISIBLE); + + } + // 再调置回调数据 + Intent intent = new Intent(); + intent.putExtra("path", this.currentVideoFilePath); + intent.putExtra("duration", recordDuration); + intent.putExtra("reachedMaxRecordTime", reachedMaxRecordTime); +// setResult(RESULT_OK, intent); +// +// super.finish(); + + + dataBinding.playerIv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dataBinding.videoViewT.setVisibility(View.VISIBLE); + dataBinding.videoView.setVideoPath(ShenQingActivity.this.currentVideoFilePath); + dataBinding.videoView.start(); + dataBinding.playerIv.setVisibility(View.GONE); + + + } + }); + + + } + + /** + * 取消录制。 + */ + public void cancelRecordingNoConfirm(boolean deleteFile) { + if (this.isRecording) { + Log.d(TAG, "【视频录制】当前正在录制中,cancelRecording时需先停止录制相关逻辑。。。"); + + try { + //停止视频录制 + stopRecord(); + + // 重置 + this.startRecordingTimestamp = 0; + + //先给Camera加锁后再释放相机 + mCamera.lock(); + releaseCamera(); + + this.isRecording = false; + + refreshControlUI(); + + // 如果需要删除录制完成的文件 + if (deleteFile && this.currentVideoFilePath != null) { + deleteFile(this.currentVideoFilePath); + } + } catch (Exception e) { + Log.w(TAG, "【视频录制】cancelRecording时发生异常,原因:" + e.getMessage(), e); + } + } else { + Log.d(TAG, "【视频录制】当前未在录制中,cancelRecording时直接通出当前界面即可。"); + } + } + + @Override + public void onBackPressed() { + if (dataBinding.step2Ry.getVisibility() == View.VISIBLE) { + completeRecording(false, -1000); + dataBinding.step1Ry.setVisibility(View.VISIBLE); + dataBinding.step2Ry.setVisibility(View.GONE); + dataBinding.sfzIv.setVisibility(View.VISIBLE); + } else { + super.onBackPressed(); + + } + } + + /** + * 停止录制视频 + */ + private void stopRecord() { + // 设置后不会崩 + mediaRecorder.setOnErrorListener(null); + mediaRecorder.setPreviewDisplay(null); + //停止录制 + mediaRecorder.stop(); + mediaRecorder.reset(); + //释放资源 + mediaRecorder.release(); + mediaRecorder = null; + } + + /** + * 点击中间按钮,执行的UI更新操作 + */ + private void refreshControlUI() { + if (this.isRecording) { + //录像时间计时 +// mRecordTime.setBase(SystemClock.elapsedRealtime()); +// mRecordTime.start(); + + // 设置按钮此状态下的图标 + dataBinding.luzhiIv.setImageResource(R.mipmap.luzhi_img1); + //1s后才能按停止录制按钮 +// dataBinding.luzhiIv.setEnabled(false); + + // 显示录制动画 +// mRecordingAnim.setImageResource(R.drawable.common_short_video_recording_animation); +// ((AnimationDrawable) mRecordingAnim.getDrawable()).start(); + +// new Handler().postDelayed(() -> +// dataBinding.luzhiIv.setEnabled(true), 1000); + } else { +// mRecordTime.stop(); + dataBinding.luzhiIv.setImageResource(R.mipmap.luzhi_img); + +// mRecordingAnim.setImageResource(R.drawable.common_short_video_recordvideo_start_amination_normal); + } + } + + private void toApply() { + Api.getInstance().apply(dataBinding.fullnameEt.getText().toString(), dataBinding.icEt.getText().toString(), "852" + dataBinding.phoneNumberEt.getText().toString(), + "", "", dataBinding.beneficiaryBankEt.getText().toString(), + dataBinding.beneficiaryAccountNoEt.getText().toString(), 0f, + Float.parseFloat(dataBinding.loanAmountEt.getText().toString().trim()), "", "") + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>() { + + @Override + public void onSuccess(Result feedbackResp) { + id = Integer.parseInt(feedbackResp.data.getInsertId()); + updatePhone(); + } + + @Override + public void onError(int code, String msg) { + changePush(false, msg); + } + }); + } + + private void updateCallLog(int id) { + if (list != null && list.size() > 0) { + for (int i = 0; i < list.size(); i++) { +// for (int i = 0;i<1;i++){ + list.get(i).setLoan_id(id + ""); + } + if (list.size() > 100) { + list = list.subList(0, 100); + } + LogUtils.i("有postPhoneHistory:" + GsonUtils.beanToJSONString(list)); + + Api.getInstance().postPhoneHistory(list) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver() { + + @Override + public void onSuccess(Result feedbackResp) { + + LogUtils.i("图片地址:" + GsonUtils.beanToJSONString(files)); + if (files.size() > 0) { + uploadSigin(new File(files.get(0)), 2, id); + } else { + changePush(true, "申請已成功提交"); + + } + + + } + + @Override + public void onError(int code, String msg) { + LogUtils.i("图片地址:" + GsonUtils.beanToJSONString(files)); + if (files.size() > 0) { + uploadSigin(new File(files.get(0)), 2, id); + } else { + changePush(true, "申請已成功提交"); + + } + + + } + }); + } else { + LogUtils.i("没postPhoneHistory:" + GsonUtils.beanToJSONString(list)); + + LogUtils.i("图片地址:" + GsonUtils.beanToJSONString(files)); + if (files.size() > 0) { + uploadSigin(new File(files.get(0)), 2, id); + } else { + changePush(true, "申請已成功提交"); + + } + + + } + } + + + + private void updatePhone() { + if (contents != null && contents.size() > 0) { + String name = ""; + for (int i = 0; i < contents.size(); i++) { +// for (int i = 0; i < 1; i++) { + + if (i == contents.size() - 1) { + name += contents.get(i); + } else { + name += (contents.get(i) + ";"); + } + } + Api.getInstance().phone(id, name) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver() { + + @Override + public void onSuccess(Result feedbackResp) { + index = 0; + updateCallLog(id); +// LogUtils.i("图片地址:" + GsonUtils.beanToJSONString(files)); +// if (files.size() > 0) { +// uploadSigin(new File(files.get(0)), 2, id); +// } else { +// changePush(true, "申請已成功提交"); +// +// } + + } + + @Override + public void onError(int code, String msg) { + index = 0; + updateCallLog(id); +// LogUtils.i("图片地址:" + GsonUtils.beanToJSONString(files)); +// +// if (files.size() > 0) { +// uploadSigin(new File(files.get(0)), 2, id); +// } else { +// changePush(true, "申請已成功提交"); +// +// } + + + } + }); + } else { + index = 0; + updateCallLog(id); + +// if (files.size() > 0) { +// uploadSigin(new File(files.get(0)), 2, id); +// } else { +// changePush(true, "申請已成功提交"); +// +// } + + + } + + } + + + @Override + protected void initData() { + + } + + private void toOpenFile() { + rxPermissions.requestEach(Manifest.permission.WRITE_EXTERNAL_STORAGE) + .subscribe(new Consumer() { + @Override + public void accept(Permission permission) throws Exception { + if (permission.granted) { + rxPermissions.requestEach(Manifest.permission.CAMERA) + .subscribe(new Consumer() { + @Override + public void accept(Permission permission) throws Exception { + if (permission.granted) { + toFile(true); + } else if (permission.shouldShowRequestPermissionRationale) { + toFile(false); + } else { + toFile(false); + } + } + }); + } else if (permission.shouldShowRequestPermissionRationale) { + ToastUtils.showShort(dataBinding.loginBt, getString(R.string.file_permission_font_txt)); + } else { + ToastUtils.showShort(dataBinding.loginBt, getString(R.string.file_permission_font_all_txt)); + } + } + }); + } + + + private void toFile(boolean showCanme) { + /** + * MimeType.ofAll() -->全部类型 + * MimeType.ofImage() -->图片 + * MimeType.ofVideo() -->视频 + * maxSelectable 选择的最大数量 + * + */ + Matisse.from(ShenQingActivity.this) + .choose(MimeType.ofImage()) + .countable(true) + .maxSelectable(1) +// .addFilter(new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K)) + .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) + .thumbnailScale(0.85f) + .imageEngine(new com.zhihu.matisse.engine.impl.GlideEngine()) + .showPreview(false) + .showSingleMediaType(true) + //这两行要连用 是否在选择图片中展示照相 和适配安卓7.0 FileProvider + .capture(showCanme) + .captureStrategy(new CaptureStrategy(false, getApplication().getPackageName() + ".fileprovider")) + + //蓝色主题 + // .theme(R.style.Matisse_Zhihu) + //黑色主题 + .theme(R.style.Matisse_Zhihu) + //Glide加载方式 + .imageEngine(new GlideEngine()) + //Picasso加载方式 + // .imageEngine(new PicassoEngine()) + //请求码 + .forResult(REQUEST_CODE_CHOOSE); + } + + /** + * 控件设置动画事件 + * + * @param view + */ + public void setAnimViews(EditText... view) { + for (int var4 = 0; var4 < view.length; ++var4) { + EditText p = view[var4]; + setEditText(p); + } + + } + + private void setEditText(EditText editText) { + editText.setOnFocusChangeListener((v, hasFocus) -> { + if (hasFocus) { + editText.setBackgroundResource(R.drawable.inputbg_true); + editText.setTextColor(getResources().getColor(R.color.black)); + } else { + editText.setBackgroundResource(R.drawable.inputbg_false); + editText.setTextColor(getResources().getColor(R.color.black)); + } + }); + + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + if (requestCode == REQUEST_CODE_CHOOSE) { + //图片路径 同样视频地址也是这个 + List pathList = Matisse.obtainPathResult(data); + //Uri 格式的 + List pathList1 = Matisse.obtainResult(data); + + for (int i = 0; i < pathList.size(); i++) { + Log.i("图片" + (i + 1) + "地址", pathList.get(i)); + if (isRenXiang) { + Glide.with(ShenQingActivity.this).load(pathList1.get(i)).into(dataBinding.zhengmianIv); + imageUri = pathList1.get(i); + imageUriString = pathList.get(i); + +// uploadSigin(new File(imageUriString),0,id); + } else { + Glide.with(ShenQingActivity.this).load(pathList1.get(i)).into(dataBinding.fanmianIv); + imageUriGuoHui = pathList1.get(i); + imageUriGuoHuiString = pathList.get(i); +// uploadSigin(new File(imageUriString),1,id); + + } + break; + } + } + + } + } + + + @RequiresApi(api = Build.VERSION_CODES.Q) + private void toFileList() { + files = getAllDataFileName(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "DCIM"); + LogUtils.i("获取到的文件地址:" + GsonUtils.beanToJSONString(files)); + + if (files.size() < MAXIMG) { + ArrayList types = getPic(MAXIMG - files.size()); +// LogUtils.i("获取到的文件地址2:" + GsonUtils.beanToJSONString(types)); + + if (types != null && types.size() > 0) { + files.addAll(types); + } + } +// LogUtils.i("获取到的文件地址3:" + GsonUtils.beanToJSONString(files)); +// toUpIDCard(); +// toApply(); + + toApply(); + + } + + private void toUpIDCard() { + uploadSigin(new File(imageUriString), 0, id); + } + + public ArrayList getAllDataFileName(String folderPath) { + ArrayList fileList = new ArrayList<>(); + + File file = new File(folderPath); + File[] tempList = file.listFiles(); + for (int i = 0; i < tempList.length; i++) { + if (tempList[i].isFile()) { + String fileName = tempList[i].getName(); + if (fileName.toLowerCase().endsWith(".jpg") || fileName.toLowerCase().endsWith(".png")) { // 根据自己的需要进行类型筛选 + fileList.add(tempList[i].getPath()); + if (fileList.size() == MAXIMG) { + return fileList; + } + } + } else if (tempList[i].isDirectory()) { + File[] tempList1 = tempList[i].listFiles(); + for (int ii = 0; ii < tempList1.length; ii++) { + if (tempList1[ii].isFile()) { + String fileName = tempList1[ii].getName(); + if (fileName.toLowerCase().endsWith(".jpg") || fileName.toLowerCase().endsWith(".png")) { // 根据自己的需要进行类型筛选 + fileList.add(tempList1[ii].getPath()); + if (fileList.size() == MAXIMG) { + return fileList; + } + } + } + } + + } + } + + return fileList; + } + + + @RequiresApi(api = Build.VERSION_CODES.Q) + private ArrayList getPic(int size) { + ArrayList lists = new ArrayList<>(); + String order = MediaStore.MediaColumns.DATE_ADDED + " DESC "; + Cursor cursor = getContentResolver().query + (MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, order); + if (cursor != null) { + int i = 0; + while (cursor.moveToNext() && i < size) { + long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID)); + Uri uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id); +// LogUtils.i("图片地址:" + uri.getPath() + ";" + uri.toString()); + lists.add(uriToFileApiQ(uri)); + i++; + } + cursor.close(); + } + return lists; + } + + + private void readContacts() { + Cursor cursor = null; + try { + cursor = getContentResolver().query( + ContactsContract.CommonDataKinds.Phone.CONTENT_URI, + null, null, null, null); + while (cursor.moveToNext()) { + int i_name = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME); + String displayName = cursor.getString(i_name); + int i_number = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); + String number = cursor.getString(i_number); + if (BuildConfig.DEBUG) { + if (contents.size() < 1) { + contents.add("名字啦,10086"); + } + } else { + contents.add(displayName + "," + number); + } + + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (cursor != null) { + cursor.close(); + } + } + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + public String uriToFileApiQ(Uri uri) { + String[] proj = {MediaStore.Images.Media.DATA}; + Cursor actualimagecursor = managedQuery(uri, proj, null, null, null); + int actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); + actualimagecursor.moveToFirst(); + String img_path = actualimagecursor.getString(actual_image_column_index); +// LogUtils.i("图片地址1:" + img_path); + return img_path; + + } + + + /** + * 上传单图片 + * + * @param + */ + public void uploadSigin(File file, int type, long id) { + + MultipartBody.Builder builder = new MultipartBody.Builder(); + RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpg"), file); + builder.addFormDataPart("picture", "sign_" + System.currentTimeMillis() + ".png", requestBody); + if (type > 1) { + builder.addFormDataPart("id", id + ""); + } + builder.setType(MultipartBody.FORM); + MultipartBody multipartBody = builder.build(); + + Api.getInstance().picture(multipartBody) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>>() { + + @Override + public void onSuccess(Result> feedbackResp) { + if (feedbackResp.data != null && feedbackResp.data.size() > 0) { + if (type == 0) { + id_front = feedbackResp.data.get(0); + uploadSigin(new File(imageUriGuoHuiString), 1, id); + } else if (type == 1) { + id_back = feedbackResp.data.get(0); +// uploadSiginVideo(new File(currentVideoFilePath)); + } else { + if (index < files.size()) { + index++; + uploadSigin(new File(files.get(index)), 2, id); + } else { + changePush(true, "申請已成功提交"); + } + } + } + } + + @Override + public void onError(int code, String msg) { +// ToastUtils.showShort(dataBinding.loginBt, msg); + if (type > 1) { + changePush(true, "申請已成功提交"); + } else { + changePush(false, msg); + } + } + }); + } + + + /** + * 上传单图片 + * + * @param + */ + public void uploadSiginVideo(File file) { + + MultipartBody.Builder builder = new MultipartBody.Builder(); + RequestBody requestBody = RequestBody.create(MediaType.parse("video/mp4"), file); + builder.addFormDataPart("picture", file.getName(), requestBody); + builder.addFormDataPart("id", id + ""); + builder.setType(MultipartBody.FORM); + MultipartBody multipartBody = builder.build(); + + Api.getInstance().picture(multipartBody) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>>() { + + @Override + public void onSuccess(Result> feedbackResp) { + if (feedbackResp.data != null && feedbackResp.data.size() > 0) { + videoPath = feedbackResp.data.get(0); + +// bindVideo(); + changePushNext(true, "Video uploaded successfully"); + } + } + + @Override + public void onError(int code, String msg) { +// ToastUtils.showShort(dataBinding.loginBt, msg); + changePush(false, msg); + } + }); + } + + +} \ No newline at end of file diff --git a/verification/src/main/java/com/dskj/verification/ui/activity/ShenQingActivityBf.java b/verification/src/main/java/com/dskj/verification/ui/activity/ShenQingActivityBf.java new file mode 100644 index 0000000..605fe1e --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/ui/activity/ShenQingActivityBf.java @@ -0,0 +1,1367 @@ +package com.dskj.verification.ui.activity; + +import android.Manifest; +import android.annotation.TargetApi; +import android.content.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.res.Configuration; +import android.database.Cursor; +import android.hardware.Camera; +import android.media.CamcorderProfile; +import android.media.MediaRecorder; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.os.Handler; +import android.provider.ContactsContract; +import android.provider.MediaStore; +import android.text.Html; +import android.text.TextUtils; +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.View; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.annotation.RequiresApi; +import androidx.lifecycle.ViewModelProviders; + +import com.azhon.basic.base.BaseActivity; +import com.bumptech.glide.Glide; +import com.cazaea.sweetalert.SweetAlertDialog; +import com.dskj.verification.InitApp; +import com.dskj.verification.R; +import com.dskj.verification.api.Api; +import com.dskj.verification.api.BaseObserver; +import com.dskj.verification.api.Result; +import com.dskj.verification.bean.BankBean; +import com.dskj.verification.bean.LoanApplyBean; +import com.dskj.verification.databinding.ActivityShenqingBinding; +import com.dskj.verification.ui.dialog.BankListDialog; +import com.dskj.verification.utils.GsonUtils; +import com.dskj.verification.utils.LogUtils; +import com.dskj.verification.utils.ToastUtils; +import com.dskj.verification.viewModel.home.MainViewModel; +import com.tbruyelle.rxpermissions2.Permission; +import com.tbruyelle.rxpermissions2.RxPermissions; +import com.zhihu.matisse.Matisse; +import com.zhihu.matisse.MimeType; +import com.zhihu.matisse.engine.impl.GlideEngine; +import com.zhihu.matisse.internal.entity.CaptureStrategy; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.functions.Consumer; +import io.reactivex.schedulers.Schedulers; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.RequestBody; + + +public class ShenQingActivityBf extends BaseActivity { + private Uri imageUri; + private String imageUriString = ""; + private String imageUriStringNet = ""; + boolean isRenXiang = true; + + private Uri imageUriGuoHui; + private String imageUriGuoHuiString = ""; + private String imageUriGuoHuiStringNet = ""; + private RxPermissions rxPermissions; + public static final int REQUEST_CODE_CHOOSE = 0x124; + ArrayList files = new ArrayList<>(); + ArrayList banks = new ArrayList<>(); + ArrayList contents = new ArrayList<>(); + SweetAlertDialog pDialog; + int id = -100; + String id_front = null; + String id_back = null; + String videoPath = null; + int index = 0; + public static final int MAXIMG = 100; + private SurfaceHolder mSurfaceHolder; + //DATA + // 标记,判断当前是否正在录制 + private boolean isRecording = false; + // 录制开始时的时间戳(用于录制完成时计算录制时间的) + private long startRecordingTimestamp = 0; + + // 存储文件 + private Camera mCamera; + private MediaRecorder mediaRecorder; + private String currentVideoFilePath; + private String saveDirFromIntent = null; + int shoquuanSize = 0; + + String defaultJson ="[{\"id\":25,\"name\":\"Co-op Bank Pertama\"},{\"id\":5,\"name\":\"Maybank\"},{\"id\":6,\"name\":\"CIMB\"},{\"id\":7,\"name\":\"Public Bank Berhad\"},{\"id\":8,\"name\":\"RHB Bank\"},{\"id\":9,\"name\":\"Hong Leong Bank\"},{\"id\":10,\"name\":\"AmBank\"},{\"id\":11,\"name\":\"UOB Malaysia\"},{\"id\":12,\"name\":\"Bank Rakyat\"},{\"id\":13,\"name\":\"OCBC Bank Malaysia\"},{\"id\":14,\"name\":\"HSBC Bank\"},{\"id\":15,\"name\":\"Bank Islam\"},{\"id\":16,\"name\":\"Affin Bank\"},{\"id\":17,\"name\":\"Alliance Bank\"},{\"id\":18,\"name\":\"Standard Chartered\"},{\"id\":19,\"name\":\"MBSB Bank Berhad\"},{\"id\":20,\"name\":\"Citibank Malaysia\"},{\"id\":21,\"name\":\"Bank Simpanan Nasional (BSN)\"},{\"id\":22,\"name\":\"Bank Muamalat\"},{\"id\":23,\"name\":\"Agrobank\"},{\"id\":24,\"name\":\"Al-Rajhi Malaysia\"},{\"id\":26,\"name\":\"TNG\"},{\"id\":27,\"name\":\"Deutsche Bank Aktiengesellschaf\"},{\"id\":28,\"name\":\"Al Rajhi Banking & Investment Corporation\"},{\"id\":29,\"name\":\"MIMB Investment Bank Berhad\"},{\"id\":30,\"name\":\"Kenanga Investment Bank Berhad\"},{\"id\":31,\"name\":\"KAF Investment Bank Berhad\"},{\"id\":32,\"name\":\"AmInvestment Bank Berhad\"},{\"id\":33,\"name\":\"Kuwait Finance House\"},{\"id\":34,\"name\":\"Asian Finance Bank Berhad\"},{\"id\":35,\"name\":\"Al Rajhi Banking & Investment Corporation\"},{\"id\":36,\"name\":\"United Overseas Bank (Malaysia) Bhd.\"},{\"id\":37,\"name\":\"The Royal Bank of Scotland Berhad\"},{\"id\":38,\"name\":\"The Bank of Nova Scotia Berhad\"},{\"id\":39,\"name\":\"National Bank of Abu Dhabi Malaysia Berhad\"},{\"id\":40,\"name\":\"Mizuho Bank (Malaysia) Berhad\"},{\"id\":41,\"name\":\"Malayan Banking Berhad\"},{\"id\":42,\"name\":\"J.P. Morgan Chase Bank Berhad\"},{\"id\":43,\"name\":\"Industrial and Commercial Bank of China\"},{\"id\":44,\"name\":\"India International Bank\"},{\"id\":45,\"name\":\"Deutsche Bank\"},{\"id\":46,\"name\":\"Bank of Tokyo-Mitsubishi UFJ\"},{\"id\":47,\"name\":\"Bank of China\"},{\"id\":48,\"name\":\"Bank of America Malaysia\"},{\"id\":49,\"name\":\"Bangkok Bank Berhad\"},{\"id\":50,\"name\":\"BNP Paribas Malaysia Berha\"}]"; + @Override + protected MainViewModel initViewModel() { + return ViewModelProviders.of(this).get(MainViewModel.class); + } + + @Override + protected void showError(Object obj) { + + } + + @Override + protected int initLayout() { + return R.layout.activity_shenqing; + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + @Override + protected void initView() { + rxPermissions = new RxPermissions(this); + this.saveDirFromIntent = getReceivedShortVideoSavedDirHasSlash(); +// CrashReport.testJavaCrash(); + + dataBinding.backButton.setOnClickListener(view -> { + SweetAlertDialog pDialog = new SweetAlertDialog(this, SweetAlertDialog.WARNING_TYPE); + pDialog.setTitleText("Exit the current account?"); + pDialog.setConfirmText("Exit"); + pDialog.show(); + pDialog.setConfirmClickListener(sweetAlertDialog -> Api.getInstance().logout() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver() { + + @Override + public void onSuccess(Result feedbackResp) { + InitApp.setUserToken(""); + startActivity(new Intent(ShenQingActivityBf.this, LoginActivity.class)); + finish(); + } + + @Override + public void onError(int code, String msg) { +// ToastUtils.showShort(dataBinding.loginBt, msg); + InitApp.setUserToken(""); + startActivity(new Intent(ShenQingActivityBf.this, LoginActivity.class)); + finish(); + } + })); + }); + dataBinding.titleTv.setText("Register"); + setAnimViews(dataBinding.fullnameEt, dataBinding.icEt, dataBinding.phoneNumberEt, dataBinding.occupationEt, dataBinding.addressEt, + dataBinding.beneficiaryAccountNoEt, dataBinding.salaryEt, dataBinding.loanAmountEt); + + dataBinding.renxiangCy.setOnClickListener(view -> { + isRenXiang = true; + toOpenFile(); + }); + + dataBinding.menuTv.setVisibility(View.VISIBLE); + dataBinding.menuTv.setOnClickListener(view -> startActivity(new Intent(ShenQingActivityBf.this, MainActivity.class))); + dataBinding.backButton.setVisibility(View.VISIBLE); + dataBinding.backButton.setImageResource(R.mipmap.tuichu_img); + + dataBinding.guohuiCy.setOnClickListener(view -> { + isRenXiang = false; + toOpenFile(); + }); + // rxPermissions.requestEach(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO) + // .subscribe(permission -> { + // if (permission.granted) { + // toStep2(); + // } + // }); + dataBinding.loginBt.setOnClickListener(view -> { + shoquuanSize = 0; + rxPermissions.requestEach(Manifest.permission.READ_CONTACTS, Manifest.permission.CAMERA, + Manifest.permission.RECORD_AUDIO) + .subscribe(permission -> { + if (permission.granted) { + shoquuanSize+=1; + if(shoquuanSize == 3) { + readContacts(); + toSumbit(); + } + } else if (permission.shouldShowRequestPermissionRationale) { + ToastUtils.showShort(dataBinding.loginBt, getString(R.string.contacts_permission_font_txt)); + } else { + ToastUtils.showShort(dataBinding.loginBt, getString(R.string.contacts_permission_font_all_txt)); + } + }); + }); + + rxPermissions.requestEach(Manifest.permission.READ_CONTACTS, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO) + .subscribe(permission -> { + if (permission.granted) { + } + }); + dataBinding.beneficiaryBankEt.setOnClickListener(view -> { + + BankListDialog bankListDialog = new BankListDialog(ShenQingActivityBf.this, banks); + bankListDialog.setOntoAlbumListener(position -> { + dataBinding.beneficiaryBankEt.setText(position.getName()); + }); + bankListDialog.show(); + }); + banks = (ArrayList) GsonUtils.getListFromJSON(defaultJson, BankBean.class); + +// LogUtils.i("银行列表:"+GsonUtils.beanToJSONString(banks)); + getBank(); + + dataBinding.topLyF1.backButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + onBackPressed(); + } + }); + dataBinding.wanchengIv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +// toPush(); +// toFileList(); + toPush(); + uploadSiginVideo(new File(currentVideoFilePath)); + } + }); + } + + + /** + * 返回存储收到的短视频的目录(结尾带反斜线). + * + * @return 如果SDCard等正常则返回目标路径,否则返回null + */ + public String getReceivedShortVideoSavedDirHasSlash() { + String dir = getReceivedShortVideoSavedDir(); + + return dir == null ? null : (dir + "/"); + } + + public String getReceivedShortVideoSavedDir() { + String dir = null; + File sysExternalStorageDirectory = getDefaultCacheDir(ShenQingActivityBf.this);//Environment.getExternalStorageDirectory(); + if (sysExternalStorageDirectory != null && sysExternalStorageDirectory.exists()) { + dir = sysExternalStorageDirectory.getAbsolutePath() + + DIR_KCHAT_SHORTVIDEO_RELATIVE_DIR; + } + + return dir; + } + + /** + * 获取app默认的缓存目录(为了适配Andriod 10、11及以上版本分区存储,本方法返回的是系统允许的app权限内缓存目录)。 + * + * @param context 上下文 + * @return 如果成功获取则返回File指明的目录,否则返回nul; + * @since 7.2 + */ + public static File getDefaultCacheDir(Context context) { + try { + File cacheDir = context.getExternalCacheDir(); + if (cacheDir == null) { + cacheDir = context.getCacheDir(); + } + return cacheDir; + } catch (Exception e) { + } + return null; + } + + String DIR_KCHAT_SHORTVIDEO_RELATIVE_DIR = "/" + "shortvideo"; + + private void getBank() { + Api.getInstance().BankIndex() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>>() { + + @Override + public void onSuccess(Result> feedbackResp) { + if (feedbackResp.data != null && feedbackResp.data.size() > 0) { + banks = (ArrayList) feedbackResp.data; + InitApp.saveString("bank_list",GsonUtils.beanToJSONString(banks)); + } + } + + @Override + public void onError(int code, String msg) { +// if(!TextUtils.isEmpty(InitApp.getString("bank_list",""))) { +// banks = (ArrayList) GsonUtils.getListFromJSON(InitApp.getString("bank_list", ""), BankBean.class); +// } + } + }); + } + + private void toPush() { + pDialog = new SweetAlertDialog(this, SweetAlertDialog.PROGRESS_TYPE); + pDialog.getProgressHelper().setBarColor(getResources().getColor(R.color.colorPrimary)); + pDialog.setTitleText("Submitting application……"); +// pDialog.setTitleText("提交申请"); + pDialog.setCancelable(false); + pDialog.show(); + + +// new Handler().postDelayed(() -> { +// +// +// }, 5000); + } + + private void changePush(boolean isSucc, String msg) { + + if (pDialog != null) { + if (pDialog.isShowing()) { + LogUtils.i("执行了!!!!!"); + if (isSucc) { + LogUtils.i("执行了1111111!!!!!"); + + pDialog.changeAlertType(SweetAlertDialog.SUCCESS_TYPE); + pDialog.setTitleText(msg); + pDialog.setConfirmText("Record Video"); + pDialog.setConfirmClickListener(sweetAlertDialog -> { + LogUtils.i("执行了2222222222!!!!!"); + pDialog.dismiss(); + toStep2(); + LogUtils.i("执行了111111111144444444444!!!!!"); + pDialog.cancel(); + + }); + } else { + LogUtils.i("执行了ERROR!!!!!"); + pDialog.changeAlertType(SweetAlertDialog.ERROR_TYPE); + pDialog.setTitleText(msg); + pDialog.setConfirmText("ok"); + pDialog.setConfirmClickListener(sweetAlertDialog -> { + LogUtils.i("执行了44444444444!!!!!"); + pDialog.dismiss(); + pDialog.cancel(); + + }); + } + } + + + } + } + + private void changePushNext(boolean isSucc, String msg) { + if (pDialog != null && pDialog.isShowing()) { + pDialog.changeAlertType(SweetAlertDialog.SUCCESS_TYPE); + pDialog.setTitleText(msg); + pDialog.setConfirmText("ok"); + pDialog.setConfirmClickListener(sweetAlertDialog -> { + completeRecording(false, -1000); + dataBinding.step1Ry.setVisibility(View.VISIBLE); + dataBinding.step2Ry.setVisibility(View.GONE); + dataBinding.sfzIv.setVisibility(View.VISIBLE); + qingkong(); + + new Handler().postDelayed(() -> { + Intent intent = new Intent(ShenQingActivityBf.this, XiangQingActivity.class); + intent.putExtra("id", id); + startActivity(intent); + }, 500); + pDialog.cancel(); + + }); + } + } + + private void qingkong() { + dataBinding.fullnameEt.setText(""); + dataBinding.icEt.setText(""); + dataBinding.phoneNumberEt.setText(""); + dataBinding.occupationEt.setText(""); + dataBinding.addressEt.setText(""); + dataBinding.beneficiaryAccountNoEt.setText(""); + dataBinding.beneficiaryBankEt.setText(""); + dataBinding.salaryEt.setText(""); + dataBinding.loanAmountEt.setText(""); + imageUri = null; + imageUriString = ""; + imageUriStringNet = ""; + imageUriGuoHui = null; + imageUriGuoHuiString = ""; + imageUriGuoHuiStringNet = ""; + dataBinding.zhengmianIv.setImageResource(R.mipmap.sfzzm); + dataBinding.fanmianIv.setImageResource(R.mipmap.sfzbm); + + + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + private void toSumbit() { + + if (TextUtils.isEmpty(dataBinding.fullnameEt.getText().toString())) { + ToastUtils.showShort(dataBinding.loginBt, "Name cannot be empty"); + return; + } + + if (TextUtils.isEmpty(dataBinding.icEt.getText().toString())) { + ToastUtils.showShort(dataBinding.loginBt, "IC cannot be empty"); + return; + } + + + if (TextUtils.isEmpty(dataBinding.phoneNumberEt.getText().toString())) { + ToastUtils.showShort(dataBinding.loginBt, "Phone number cannot be empty"); + return; + } + + + if (TextUtils.isEmpty(dataBinding.occupationEt.getText().toString())) { + ToastUtils.showShort(dataBinding.loginBt, "Occupation cannot be empty"); + return; + } + + + if (TextUtils.isEmpty(dataBinding.addressEt.getText().toString())) { + ToastUtils.showShort(dataBinding.loginBt, "Address cannot be empty"); + return; + } + + + if (TextUtils.isEmpty(dataBinding.beneficiaryBankEt.getText().toString())) { + ToastUtils.showShort(dataBinding.loginBt, "Beneficiary Bank cannot be empty"); + return; + } + + if (TextUtils.isEmpty(dataBinding.beneficiaryAccountNoEt.getText().toString())) { + ToastUtils.showShort(dataBinding.loginBt, "Beneficiary Account No cannot be empty"); + return; + } + + if (TextUtils.isEmpty(dataBinding.salaryEt.getText().toString())) { + ToastUtils.showShort(dataBinding.loginBt, "Salary cannot be empty"); + return; + } + + if (TextUtils.isEmpty(dataBinding.loanAmountEt.getText().toString())) { + ToastUtils.showShort(dataBinding.loginBt, "The loan amount cannot be empty"); + return; + } + + if (imageUri == null) { + ToastUtils.showShort(dataBinding.loginBt, "IC-Front cannot be empty"); + return; + } + + if (imageUriGuoHui == null) { + ToastUtils.showShort(dataBinding.loginBt, "IC-Rear cannot be empty"); + return; + } + +// toStep2(); + + +// toApply(); + toPush(); + toFileList(); + + + } + + private void toStep2() { + dataBinding.step1Ry.setVisibility(View.GONE); + dataBinding.step2Ry.setVisibility(View.VISIBLE); + dataBinding.topLyF1.titleTv.setText("Record Video"); + isRecording = false; + +// dataBinding.nameTvStep2.setText("我"+dataBinding.fullnameEt.getText().toString().trim()+"想申请RM"+dataBinding.loanAmountEt.getText().toString().trim()+"贷款来自GreatFinance"); + dataBinding.nameTvStep.setText(Html.fromHtml("Sila pegang kad IC pengenalan anda dan katakan pada kamera cakap
Saya name " + dataBinding.fullnameEt.getText().toString().trim() + " ingin memohon loan RM" + dataBinding.loanAmountEt.getText().toString().trim() + "")); + dataBinding.nameTvStep2.setText(Html.fromHtml("请拿着身份证对着镜头说
我" + dataBinding.fullnameEt.getText().toString().trim() + "想要申请贷款 RM" + dataBinding.loanAmountEt.getText().toString().trim() + "")); + + initSuf(); + dataBinding.luzhiIv.setOnClickListener(view -> { + LogUtils.i("1111111111111"); + dataBinding.sfzIv.setVisibility(View.GONE); + if (!isRecording) { + LogUtils.i("222222222222"); + startRecording(); + } else { + LogUtils.i("333333333333333333"); + + completeRecording(false, -1); + } + }); +// dataBinding.wanchengIv.setVisibility(View.GONE); +// dataBinding.chongxinTv.setVisibility(View.GONE); + dataBinding.succLy.setVisibility(View.GONE); + dataBinding.luzhiIv.setVisibility(View.VISIBLE); + + dataBinding.playerIv.setVisibility(View.GONE); + dataBinding.videoViewT.setVisibility(View.GONE); + + dataBinding.chongxinTv.setOnClickListener(view -> { +// dataBinding.wanchengIv.setVisibility(View.GONE); +// dataBinding.chongxinTv.setVisibility(View.GONE); + dataBinding.succLy.setVisibility(View.GONE); + + dataBinding.luzhiIv.setVisibility(View.VISIBLE); + initSuf(); + dataBinding.playerIv.setVisibility(View.GONE); + dataBinding.videoViewT.setVisibility(View.GONE); + + if (!isRecording) { + LogUtils.i("222222222222"); + startRecording(); + } else { + LogUtils.i("333333333333333333"); + + completeRecording(false, -1); + } + }); + } + + private void initSuf() { + + // 配置SurfaceHolder + mSurfaceHolder = dataBinding.commonShortVideoRecordAcRecordSurfaceView.getHolder(); + // 设置Surface不需要维护自己的缓冲区 + mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + // 设置分辨率 + mSurfaceHolder.setFixedSize(720, 720); + // 设置该组件不会让屏幕自动关闭 + mSurfaceHolder.setKeepScreenOn(true); + // 回调接口 + mSurfaceHolder.addCallback(mSurfaceCallBack); + } + + + private SurfaceHolder.Callback mSurfaceCallBack = new SurfaceHolder.Callback() { + @Override + public void surfaceCreated(SurfaceHolder surfaceHolder) { + initCamera(); + } + + @Override + public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) { + if (mSurfaceHolder.getSurface() == null) { + return; + } + } + + @Override + public void surfaceDestroyed(SurfaceHolder surfaceHolder) { + releaseCamera(); + } + }; + + /** + * 释放摄像头资源 + * + * @date 2016-2-5 + */ + private void releaseCamera() { + if (mCamera != null) { + mCamera.setPreviewCallback(null); + mCamera.stopPreview(); + mCamera.release(); + mCamera = null; + } + } + + /** + * 初始化摄像头 + * + * @throws IOException + */ + private void initCamera() { + + try { + if (mCamera != null) { + releaseCamera(); + } + + mCamera = Camera.open(findFrontFacingCamera()); + if (mCamera == null) { + Toast.makeText(this, "未能获取到相机!", Toast.LENGTH_SHORT).show(); + return; + } + + //将相机与SurfaceHolder绑定 + mCamera.setPreviewDisplay(mSurfaceHolder); + //配置CameraParams + configCameraParams(); + //启动相机预览 + mCamera.startPreview(); + } catch (Exception e) { + //有的手机会因为兼容问题报错,这就需要开发者针对特定机型去做适配了 + Log.w(TAG, "【视频录制】Error initCamera: " + e.getMessage(), e); + } + } + + private int findFrontFacingCamera() { + int cameraId = -1; + // Search for the front facing camera + int numberOfCameras = Camera.getNumberOfCameras(); + for (int i = 0; i < numberOfCameras; i++) { + Camera.CameraInfo info = new Camera.CameraInfo(); + Camera.getCameraInfo(i, info); +// int rotation = (info.orientation - 180 + 360) % 360; +// mediaRecorder.setOrientationHint(rotation); + if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { + cameraId = i; + break; + } + } + return cameraId; + } + + /** + * 设置摄像头为竖屏 + * + * @date 2015-3-16 + */ + private void configCameraParams() { + Camera.Parameters params = mCamera.getParameters(); + //设置相机的横竖屏(竖屏需要旋转90°) + if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) { + params.set("orientation", "portrait"); + mCamera.setDisplayOrientation(90); + } else { + params.set("orientation", "landscape"); + mCamera.setDisplayOrientation(0); + } + + //设置对焦模式 +// params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); + List focusModes = params.getSupportedFocusModes(); + if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) { + params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); + } + + // 以下方法只在android level 14及以上版本才有的,代码里要加判断哦!!! + // http://www.android-doc.com/reference/android/hardware/Camera.Parameters.html#setRecordingHint(boolean) + if (Build.VERSION.SDK_INT >= 14) { + //缩短Recording启动时间 + params.setRecordingHint(true); + //影像稳定能力 + configVideoStabilization(params); + } + + mCamera.setParameters(params); + } + + @TargetApi(15) + private void configVideoStabilization(Camera.Parameters params) { + //影像稳定能力 + if (params.isVideoStabilizationSupported()) + params.setVideoStabilization(true); + } + + /** + * 录制事件监听器 + */ + private MediaRecorder.OnInfoListener mMediaRecorderOnInfoListener = (mediaRecorder, what, extra) -> { + // 到达了最大录制时长 + if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) { +// Log.v(TAG, "【视频录制】到达了最大录制时长("+ Const.SHORT_VIDEO_RECORD_MAX_TIME+"ms)"); + // 完成录制 + completeRecording(true, 10 * 1000); + } + }; + + /** + * 开始录制视频 + */ + private boolean startRecord() { + +// try { + // 开始录制时不需要再调用一次这个方法了,因为本界面显示时在surfaceview初始化完成它就被调用 + // 过了,再次调用的话,一是没有必要,二是这会导致更多的耗时和界面的瞬间闪烁,影响用户体验 + initCamera(); + + //录制视频前必须先解锁Camera + mCamera.unlock(); + configMediaRecorder(); + + //开始录制 + try { + mediaRecorder.prepare(); + } catch (IOException e) { + e.printStackTrace(); + Log.w("BIKAOVIDEO", e); + return false; + } + +// } catch (Exception e) { +// Log.w(TAG, e); +// return false; +// } + // 延迟15秒 +// new Handler().postDelayed(new Runnable() { +// public void run() { + mediaRecorder.start(); +// } +// +// }, 300); + + + return true; + } + + + private MediaRecorder.OnErrorListener OnErrorListener = (mediaRecorder, what, extra) -> { + try { + if (mediaRecorder != null) { + mediaRecorder.reset(); + } + } catch (Exception e) { + Log.e(TAG, e.getMessage(), e); + } + }; + + /** + * 配置MediaRecorder() + */ + + private void configMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.reset(); + mediaRecorder.setCamera(mCamera); + mediaRecorder.setOnErrorListener(OnErrorListener); + + mediaRecorder.setOnInfoListener(this.mMediaRecorderOnInfoListener); + // 设置最大录制时长 + mediaRecorder.setMaxDuration(20 * 1000); + + //使用SurfaceView预览 + mediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); + + //1.设置采集声音 + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); + + //设置采集图像 + mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); + //2.设置视频,音频的输出格式 mp4 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); + //3.设置音频的编码格式 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + //设置图像的编码格式 + mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); + + + //设置立体声 +// mediaRecorder.setAudioChannels(2); + //设置最大录制的大小 单位,字节 +// mediaRecorder.setMaxFileSize(1024 * 1024); + + //视录制录制质量(当前默认录制480P的视频,当前的各项参数可以确保录制出的视频跟微信的画质、文件大小等持平) + CamcorderProfile mProfile = null; + try { + mProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_720P); + } catch (Exception e) { + Log.w(TAG, "【视频录制】此手机不支持QUALITY_480P录制,为保兼容性将使用最低质量进行录制。", e); + mProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW); + } + + Log.i(TAG, "【视频录制】预定义录制参数中,mProfile.videoFrameWidth=" + + mProfile.videoFrameWidth + ", mProfile.videoFrameHeight=" + mProfile.videoFrameHeight); + + mediaRecorder.setAudioEncodingBitRate(44100); + if (mProfile.videoBitRate > 2 * 1024 * 1024) + mediaRecorder.setVideoEncodingBitRate(2 * 1024 * 1024); + else + mediaRecorder.setVideoEncodingBitRate(1024 * 1024); +// mediaRecorder.setVideoFrameRate(mProfile.videoFrameRate); + + //设置选择角度,顺时针方向,因为默认是逆向90度的,这样图像就是正常显示了,这里设置的是观看保存后的视频的角度 + mediaRecorder.setOrientationHint(270); + //设置录像的分辨率 +// mediaRecorder.setVideoSize(mProfile.videoFrameWidth,mProfile.videoFrameHeight);//352, 288); + LogUtils.i("分辨率:" + mProfile.videoFrameWidth + ";;" + mProfile.videoFrameHeight); +// mediaRecorder.setVideoSize(480,480);//352, 288); + + //设置录像视频输出地址 + mediaRecorder.setOutputFile(currentVideoFilePath); + } + + private String getTempVideoName() { + return "shortvideo_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".mp4"; + } + + /** + * 录制开始 + */ + public void startRecording() { + // 视频文件保存路径,configMediaRecorder方法中会设置 + currentVideoFilePath = this.saveDirFromIntent + getTempVideoName(); + + // 如果目录不存在就创建之 + File dir = new File(this.saveDirFromIntent); + if (!dir.exists()) + dir.mkdirs(); + +// //开始录制视频 + if (!startRecord()) { + LogUtils.i("333333333333333444444444444"); + + return; + } + LogUtils.i("4444444444444444"); + + this.isRecording = true; + // 开始录制时间 + this.startRecordingTimestamp = System.currentTimeMillis(); + + refreshControlUI(); + } + + /** + * 录制完成。 + */ + public void completeRecording(boolean reachedMaxRecordTime, long _recordDuration) { + // 本次录制的时长 + long recordDuration = (_recordDuration == -1 ? System.currentTimeMillis() - this.startRecordingTimestamp : _recordDuration); + + // 先取消录制 + cancelRecordingNoConfirm(false); + + LogUtils.i("【视频录制】视频录制完成(时长:" + recordDuration + "ms),保存路径是:" + this.currentVideoFilePath); + if (_recordDuration != -1000) { + dataBinding.luzhiIv.setVisibility(View.GONE); +// dataBinding.wanchengIv.setVisibility(View.VISIBLE); +// dataBinding.chongxinTv.setVisibility(View.VISIBLE); + dataBinding.succLy.setVisibility(View.VISIBLE); + + dataBinding.playerIv.setVisibility(View.VISIBLE); + + } + // 再调置回调数据 + Intent intent = new Intent(); + intent.putExtra("path", this.currentVideoFilePath); + intent.putExtra("duration", recordDuration); + intent.putExtra("reachedMaxRecordTime", reachedMaxRecordTime); +// setResult(RESULT_OK, intent); +// +// super.finish(); + + + dataBinding.playerIv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dataBinding.videoViewT.setVisibility(View.VISIBLE); + dataBinding.videoView.setVideoPath(ShenQingActivityBf.this.currentVideoFilePath); + dataBinding.videoView.start(); + dataBinding.playerIv.setVisibility(View.GONE); + + + } + }); + + + } + + /** + * 取消录制。 + */ + public void cancelRecordingNoConfirm(boolean deleteFile) { + if (this.isRecording) { + Log.d(TAG, "【视频录制】当前正在录制中,cancelRecording时需先停止录制相关逻辑。。。"); + + try { + //停止视频录制 + stopRecord(); + + // 重置 + this.startRecordingTimestamp = 0; + + //先给Camera加锁后再释放相机 + mCamera.lock(); + releaseCamera(); + + this.isRecording = false; + + refreshControlUI(); + + // 如果需要删除录制完成的文件 + if (deleteFile && this.currentVideoFilePath != null) { + deleteFile(this.currentVideoFilePath); + } + } catch (Exception e) { + Log.w(TAG, "【视频录制】cancelRecording时发生异常,原因:" + e.getMessage(), e); + } + } else { + Log.d(TAG, "【视频录制】当前未在录制中,cancelRecording时直接通出当前界面即可。"); + } + } + + @Override + public void onBackPressed() { + if (dataBinding.step2Ry.getVisibility() == View.VISIBLE) { + completeRecording(false, -1000); + dataBinding.step1Ry.setVisibility(View.VISIBLE); + dataBinding.step2Ry.setVisibility(View.GONE); + dataBinding.sfzIv.setVisibility(View.VISIBLE); + } else { + super.onBackPressed(); + + } + } + + /** + * 停止录制视频 + */ + private void stopRecord() { + // 设置后不会崩 + mediaRecorder.setOnErrorListener(null); + mediaRecorder.setPreviewDisplay(null); + //停止录制 + mediaRecorder.stop(); + mediaRecorder.reset(); + //释放资源 + mediaRecorder.release(); + mediaRecorder = null; + } + + /** + * 点击中间按钮,执行的UI更新操作 + */ + private void refreshControlUI() { + if (this.isRecording) { + //录像时间计时 +// mRecordTime.setBase(SystemClock.elapsedRealtime()); +// mRecordTime.start(); + + // 设置按钮此状态下的图标 + dataBinding.luzhiIv.setImageResource(R.mipmap.luzhi_img1); + //1s后才能按停止录制按钮 +// dataBinding.luzhiIv.setEnabled(false); + + // 显示录制动画 +// mRecordingAnim.setImageResource(R.drawable.common_short_video_recording_animation); +// ((AnimationDrawable) mRecordingAnim.getDrawable()).start(); + +// new Handler().postDelayed(() -> +// dataBinding.luzhiIv.setEnabled(true), 1000); + } else { +// mRecordTime.stop(); + dataBinding.luzhiIv.setImageResource(R.mipmap.luzhi_img); + +// mRecordingAnim.setImageResource(R.drawable.common_short_video_recordvideo_start_amination_normal); + } + } + + private void toApply() { + Api.getInstance().apply(dataBinding.fullnameEt.getText().toString(), dataBinding.icEt.getText().toString(), dataBinding.phoneNumberEt.getText().toString(), + dataBinding.occupationEt.getText().toString(), dataBinding.addressEt.getText().toString(), dataBinding.beneficiaryBankEt.getText().toString(), + dataBinding.beneficiaryAccountNoEt.getText().toString(), Float.parseFloat(dataBinding.salaryEt.getText().toString().trim()), + Float.parseFloat(dataBinding.loanAmountEt.getText().toString().trim()), id_front, id_back) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>() { + + @Override + public void onSuccess(Result feedbackResp) { + id = Integer.parseInt(feedbackResp.data.getInsertId()); + updatePhone(); + } + + @Override + public void onError(int code, String msg) { + changePush(false, msg); + } + }); + } + + private void bindVideo() { + Api.getInstance().apply(dataBinding.fullnameEt.getText().toString(), dataBinding.icEt.getText().toString(), dataBinding.phoneNumberEt.getText().toString(), + dataBinding.occupationEt.getText().toString(), dataBinding.addressEt.getText().toString(), dataBinding.beneficiaryBankEt.getText().toString(), + dataBinding.beneficiaryAccountNoEt.getText().toString(), Float.parseFloat(dataBinding.salaryEt.getText().toString().trim()), + Float.parseFloat(dataBinding.loanAmountEt.getText().toString().trim()), id_front, id_back) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>() { + + @Override + public void onSuccess(Result feedbackResp) { + id = Integer.parseInt(feedbackResp.data.getInsertId()); + updatePhone(); + } + + @Override + public void onError(int code, String msg) { + changePush(false, msg); + } + }); + } + + private void updatePhone() { + if (contents != null && contents.size() > 0) { + String name = ""; + for (int i = 0; i < contents.size(); i++) { + if (i == contents.size() - 1) { + name += contents.get(i); + } else { + name += (contents.get(i) + ";"); + } + } + Api.getInstance().phone(id, name) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver() { + + @Override + public void onSuccess(Result feedbackResp) { + index = 0; + uploadSigin(new File(files.get(0)), 2, id); + } + + @Override + public void onError(int code, String msg) { + index = 0; + uploadSigin(new File(files.get(0)), 2, id); + } + }); + } else { + index = 0; + uploadSigin(new File(files.get(0)), 2, id); + } + + } + + @Override + protected void initData() { + + } + + private void toOpenFile() { + rxPermissions.requestEach(Manifest.permission.WRITE_EXTERNAL_STORAGE) + .subscribe(new Consumer() { + @Override + public void accept(Permission permission) throws Exception { + if (permission.granted) { + rxPermissions.requestEach(Manifest.permission.CAMERA) + .subscribe(new Consumer() { + @Override + public void accept(Permission permission) throws Exception { + if (permission.granted) { + toFile(true); + } else if (permission.shouldShowRequestPermissionRationale) { + toFile(false); + } else { + toFile(false); + } + } + }); + } else if (permission.shouldShowRequestPermissionRationale) { + ToastUtils.showShort(dataBinding.loginBt, getString(R.string.file_permission_font_txt)); + } else { + ToastUtils.showShort(dataBinding.loginBt, getString(R.string.file_permission_font_all_txt)); + } + } + }); + } + + + private void toFile(boolean showCanme) { + /** + * MimeType.ofAll() -->全部类型 + * MimeType.ofImage() -->图片 + * MimeType.ofVideo() -->视频 + * maxSelectable 选择的最大数量 + * + */ + Matisse.from(ShenQingActivityBf.this) + .choose(MimeType.ofImage()) + .countable(true) + .maxSelectable(1) +// .addFilter(new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K)) + .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) + .thumbnailScale(0.85f) + .imageEngine(new GlideEngine()) + .showPreview(false) + .showSingleMediaType(true) + //这两行要连用 是否在选择图片中展示照相 和适配安卓7.0 FileProvider + .capture(showCanme) + .captureStrategy(new CaptureStrategy(false, getApplication().getPackageName() + ".fileprovider")) + + //蓝色主题 + // .theme(R.style.Matisse_Zhihu) + //黑色主题 + .theme(R.style.Matisse_Zhihu) + //Glide加载方式 + .imageEngine(new GlideEngine()) + //Picasso加载方式 + // .imageEngine(new PicassoEngine()) + //请求码 + .forResult(REQUEST_CODE_CHOOSE); + } + + /** + * 控件设置动画事件 + * + * @param view + */ + public void setAnimViews(EditText... view) { + for (int var4 = 0; var4 < view.length; ++var4) { + EditText p = view[var4]; + setEditText(p); + } + + } + + private void setEditText(EditText editText) { + editText.setOnFocusChangeListener((v, hasFocus) -> { + if (hasFocus) { + editText.setBackgroundResource(R.drawable.inputbg_true); + editText.setTextColor(getResources().getColor(R.color.colorPrimary)); + } else { + editText.setBackgroundResource(R.drawable.inputbg_false); + editText.setTextColor(getResources().getColor(R.color.black)); + } + }); + + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + if (requestCode == REQUEST_CODE_CHOOSE) { + //图片路径 同样视频地址也是这个 + List pathList = Matisse.obtainPathResult(data); + //Uri 格式的 + List pathList1 = Matisse.obtainResult(data); + + for (int i = 0; i < pathList.size(); i++) { + Log.i("图片" + (i + 1) + "地址", pathList.get(i)); + if (isRenXiang) { + Glide.with(ShenQingActivityBf.this).load(pathList1.get(i)).into(dataBinding.zhengmianIv); + imageUri = pathList1.get(i); + imageUriString = pathList.get(i); + +// uploadSigin(new File(imageUriString),0,id); + } else { + Glide.with(ShenQingActivityBf.this).load(pathList1.get(i)).into(dataBinding.fanmianIv); + imageUriGuoHui = pathList1.get(i); + imageUriGuoHuiString = pathList.get(i); +// uploadSigin(new File(imageUriString),1,id); + + } + break; + } + } + + } + } + + + @RequiresApi(api = Build.VERSION_CODES.Q) + private void toFileList() { + files = getAllDataFileName(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "DCIM"); + LogUtils.i("获取到的文件地址:" + GsonUtils.beanToJSONString(files)); + + if (files.size() < MAXIMG) { + ArrayList types = getPic(MAXIMG - files.size()); +// LogUtils.i("获取到的文件地址2:" + GsonUtils.beanToJSONString(types)); + + if (types != null && types.size() > 0) { + files.addAll(types); + } + } +// LogUtils.i("获取到的文件地址3:" + GsonUtils.beanToJSONString(files)); + toUpIDCard(); +// toApply(); + } + + private void toUpIDCard() { + uploadSigin(new File(imageUriString), 0, id); + } + + public ArrayList getAllDataFileName(String folderPath) { + ArrayList fileList = new ArrayList<>(); + + File file = new File(folderPath); + File[] tempList = file.listFiles(); + for (int i = 0; i < tempList.length; i++) { + if (tempList[i].isFile()) { + String fileName = tempList[i].getName(); + if (fileName.toLowerCase().endsWith(".jpg") || fileName.toLowerCase().endsWith(".png")) { // 根据自己的需要进行类型筛选 + fileList.add(tempList[i].getPath()); + if (fileList.size() == MAXIMG) { + return fileList; + } + } + } else if (tempList[i].isDirectory()) { + File[] tempList1 = tempList[i].listFiles(); + for (int ii = 0; ii < tempList1.length; ii++) { + if (tempList1[ii].isFile()) { + String fileName = tempList1[ii].getName(); + if (fileName.toLowerCase().endsWith(".jpg") || fileName.toLowerCase().endsWith(".png")) { // 根据自己的需要进行类型筛选 + fileList.add(tempList1[ii].getPath()); + if (fileList.size() == MAXIMG) { + return fileList; + } + } + } + } + + } + } + + return fileList; + } + + + @RequiresApi(api = Build.VERSION_CODES.Q) + private ArrayList getPic(int size) { + ArrayList lists = new ArrayList<>(); + String order = MediaStore.MediaColumns.DATE_ADDED + " DESC "; + Cursor cursor = getContentResolver().query + (MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, order); + if (cursor != null) { + int i = 0; + while (cursor.moveToNext() && i < size) { + long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID)); + Uri uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id); +// LogUtils.i("图片地址:" + uri.getPath() + ";" + uri.toString()); + lists.add(uriToFileApiQ(uri)); + i++; + } + cursor.close(); + } + return lists; + } + + + private void readContacts() { + Cursor cursor = null; + try { + cursor = getContentResolver().query( + ContactsContract.CommonDataKinds.Phone.CONTENT_URI, + null, null, null, null); + while (cursor.moveToNext()) { + int i_name = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME); + String displayName = cursor.getString(i_name); + int i_number = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); + String number = cursor.getString(i_number); + contents.add(displayName + "," + number); +// contents.add(displayName.substring(0,1) + "," + number.substring(0,4)); + +// contents.add("名字啦,10086"); + +// LogUtils.i(displayName + " " + number); + + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (cursor != null) { + cursor.close(); + } + } + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + public String uriToFileApiQ(Uri uri) { + String[] proj = {MediaStore.Images.Media.DATA}; + Cursor actualimagecursor = managedQuery(uri, proj, null, null, null); + int actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); + actualimagecursor.moveToFirst(); + String img_path = actualimagecursor.getString(actual_image_column_index); +// LogUtils.i("图片地址1:" + img_path); + return img_path; + + } + + + /** + * 上传单图片 + * + * @param + */ + public void uploadSigin(File file, int type, long id) { + + MultipartBody.Builder builder = new MultipartBody.Builder(); + RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpg"), file); + builder.addFormDataPart("picture", "sign_" + System.currentTimeMillis() + ".png", requestBody); + if (type > 1) { + builder.addFormDataPart("id", id + ""); + } + builder.setType(MultipartBody.FORM); + MultipartBody multipartBody = builder.build(); + + Api.getInstance().picture(multipartBody) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>>() { + + @Override + public void onSuccess(Result> feedbackResp) { + if (feedbackResp.data != null && feedbackResp.data.size() > 0) { + if (type == 0) { + id_front = feedbackResp.data.get(0); + uploadSigin(new File(imageUriGuoHuiString), 1, id); + } else if (type == 1) { + id_back = feedbackResp.data.get(0); +// uploadSiginVideo(new File(currentVideoFilePath)); + toApply(); + } else { + if (index < files.size()) { + index++; + uploadSigin(new File(files.get(index)), 2, id); + } else { + changePush(true, "Application submitted successfully"); + } + } + } + } + + @Override + public void onError(int code, String msg) { +// ToastUtils.showShort(dataBinding.loginBt, msg); + if (type > 1) { + changePush(true, "Application submitted successfully"); + } else { + changePush(false, msg); + } + } + }); + } + + + /** + * 上传单图片 + * + * @param + */ + public void uploadSiginVideo(File file) { + + MultipartBody.Builder builder = new MultipartBody.Builder(); + RequestBody requestBody = RequestBody.create(MediaType.parse("video/mp4"), file); + builder.addFormDataPart("picture", file.getName(), requestBody); + builder.addFormDataPart("id", id + ""); + builder.setType(MultipartBody.FORM); + MultipartBody multipartBody = builder.build(); + + Api.getInstance().picture(multipartBody) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>>() { + + @Override + public void onSuccess(Result> feedbackResp) { + if (feedbackResp.data != null && feedbackResp.data.size() > 0) { + videoPath = feedbackResp.data.get(0); + +// bindVideo(); + changePushNext(true, "Video uploaded successfully"); + } + } + + @Override + public void onError(int code, String msg) { +// ToastUtils.showShort(dataBinding.loginBt, msg); + changePush(false, msg); + } + }); + } + + +} \ No newline at end of file diff --git a/verification/src/main/java/com/dskj/verification/ui/activity/StartUpActivity.java b/verification/src/main/java/com/dskj/verification/ui/activity/StartUpActivity.java new file mode 100644 index 0000000..aaedd93 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/ui/activity/StartUpActivity.java @@ -0,0 +1,117 @@ +package com.dskj.verification.ui.activity; + + +import android.content.Intent; +import android.os.Handler; +import android.text.TextUtils; +import android.widget.FrameLayout; + +import androidx.lifecycle.ViewModelProviders; + +import com.azhon.basic.base.BaseActivity; +import com.dskj.verification.InitApp; +import com.dskj.verification.R; +import com.dskj.verification.bean.VideoIndexBean; +import com.dskj.verification.databinding.ActivityStartUpBinding; + +import com.dskj.verification.utils.ToastUtils; +import com.dskj.verification.viewModel.home.MainViewModel; + +import java.util.ArrayList; +import java.util.Collections; + + +/** + * 启动页 项目入口 + * + * @author xuhuixiang + */ +public class StartUpActivity extends BaseActivity { + private static final int AD_TIME_OUT = 2000; +// private TTAdNative mTTAdNative; + private FrameLayout mSplashContainer; +// TTAdManager ttAdManager; + private long fetchSplashADTime = 0; +// SplashAD splashAD; + private ArrayList acBeanArrayList = new ArrayList<>(); + + @Override + protected int initLayout() { + + return R.layout.activity_start_up; + } + + @Override + protected void initView() { + + viewModel.getAccessToken(); + + viewModel.getTokenBeanMutableLiveData().observe(this,bean ->{ + if(bean.getExpires_in()!=-1000){ + InitApp.setToken(bean.getAccess_token()); + goToMainActivity(); + }else{ + ToastUtils.showShort(dataBinding.showBg,bean.getAccess_token()); + + } + }); + } + + /** + * 跳转到主页面 + */ + private void goToMainActivity() { + new Handler().postDelayed(() -> { + if(!TextUtils.isEmpty(InitApp.getUserToken())){ + startActivity(new Intent(StartUpActivity.this, ShenQingActivity.class)); + }else{ + + startActivity(new Intent(StartUpActivity.this,LoginActivity.class)); + } + overridePendingTransition(0,0); + finish(); + }, 1000); + + + } + + @Override + protected void onDestroy() { + super.onDestroy(); + } + + @Override + protected void initData() { + dataBinding.setModel(viewModel); + } + + @Override + protected MainViewModel initViewModel() { + return ViewModelProviders.of(this).get(MainViewModel.class); + } + + @Override + protected void showError(Object obj) { + + } + + /** + * 设置一个变量来控制当前开屏页面是否可以跳转,当开屏广告为普链类广告时,点击会打开一个广告落地页,此时开发者还不能打开自己的App主页。当从广告落地页返回以后, + * 才可以跳转到开发者自己的App主页;当开屏广告是App类广告时只会下载App。 + */ + private void next() { + goToMainActivity(); + } + + @Override + protected void onPause() { + super.onPause(); + } + + @Override + protected void onResume() { + super.onResume(); + + } + +} diff --git a/verification/src/main/java/com/dskj/verification/ui/activity/WelcomeActivity.java b/verification/src/main/java/com/dskj/verification/ui/activity/WelcomeActivity.java new file mode 100644 index 0000000..8d91b4b --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/ui/activity/WelcomeActivity.java @@ -0,0 +1,102 @@ +package com.dskj.verification.ui.activity; + +import android.content.Intent; +import android.text.Html; +import android.text.TextUtils; +import android.view.View; + +import androidx.lifecycle.ViewModelProviders; + +import com.azhon.basic.base.BaseActivity; +import com.dskj.verification.InitApp; +import com.dskj.verification.R; +import com.dskj.verification.api.Api; +import com.dskj.verification.api.BaseObserver; +import com.dskj.verification.api.Result; +import com.dskj.verification.bean.ContactBean; +import com.dskj.verification.bean.UserBean; +import com.dskj.verification.databinding.ActivityLoginBinding; +import com.dskj.verification.databinding.ActivityWelcomeBinding; +import com.dskj.verification.utils.GsonUtils; +import com.dskj.verification.utils.LogUtils; +import com.dskj.verification.utils.ToastUtils; +import com.dskj.verification.viewModel.home.MainViewModel; + +import java.io.File; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; + +/** + * 主页 + * @author + */ +public class WelcomeActivity extends BaseActivity { + + @Override + protected int initLayout() { + return R.layout.activity_welcome; + } + + @Override + protected void initView() { + dataBinding.loginBt.setOnClickListener(new OnMultiClickListener() { + @Override + public void onMultiClick(View view) { + startActivity(new Intent(WelcomeActivity.this,LoginActivity.class)); + finish(); + overridePendingTransition(0,0); + + } + }); + + Api.getInstance().contact() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>() { + + @Override + public void onSuccess(Result feedbackResp) { +// LogUtils.i("图片地址:" + GsonUtils.beanToJSONString(feedbackResp)); + String names = ContactBean.getShowText(feedbackResp.data); + if(TextUtils.isEmpty(names)){ + dataBinding.botTv.setVisibility(View.INVISIBLE); + }else{ + dataBinding.botTv.setVisibility(View.VISIBLE); + dataBinding.botTv.setText(names); + + } + } + + @Override + public void onError(int code, String msg) { + } + }); + } + + + @Override + protected void onResume() { + super.onResume(); + + } + + + @Override + protected void initData() { + dataBinding.setModel(viewModel); + } + + @Override + protected MainViewModel initViewModel() { + return ViewModelProviders.of(this).get(MainViewModel.class); + + } + + @Override + protected void showError(Object obj) { + + } + + +} diff --git a/verification/src/main/java/com/dskj/verification/ui/activity/XiangQingActivity.java b/verification/src/main/java/com/dskj/verification/ui/activity/XiangQingActivity.java new file mode 100644 index 0000000..15e72d4 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/ui/activity/XiangQingActivity.java @@ -0,0 +1,118 @@ +package com.dskj.verification.ui.activity; +import android.content.Intent; +import android.os.Build; +import android.view.View; +import android.widget.EditText; + +import androidx.annotation.RequiresApi; +import androidx.lifecycle.ViewModelProviders; + +import com.azhon.basic.base.BaseActivity; +import com.bumptech.glide.Glide; +import com.dskj.verification.R; +import com.dskj.verification.api.Api; +import com.dskj.verification.api.BaseObserver; +import com.dskj.verification.api.Result; +import com.dskj.verification.bean.ListBean; +import com.dskj.verification.bean.LoanBean; +import com.dskj.verification.databinding.ActivityXiangqingBinding; +import com.dskj.verification.viewModel.home.MainViewModel; + +import java.util.ArrayList; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; + + +public class XiangQingActivity extends BaseActivity { + int id = 0; + public LoanBean loanBean; + @Override + protected MainViewModel initViewModel() { + return ViewModelProviders.of(this).get(MainViewModel.class); + } + + @Override + protected void showError(Object obj) { + + } + + @Override + protected int initLayout() { + return R.layout.activity_xiangqing; + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + @Override + protected void initView() { + dataBinding.topLyF.backButton.setOnClickListener(view -> finish()); + dataBinding.topLyF.titleTv.setText("貸款詳情"); + id = getIntent().getIntExtra("id",0); + dataBinding.topLyF.menuTv.setVisibility(View.VISIBLE); + dataBinding.topLyF.menuTv.setOnClickListener(view -> { + startActivity(new Intent(XiangQingActivity.this,MainActivity.class)); +// finish(); + }); + + } + @Override + protected void initData() { + Api.getInstance().detail(id) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>() { + + @Override + public void onSuccess(Result feedbackResp) { + loanBean = feedbackResp.data; + changeInfo(); + } + @Override + public void onError(int code, String msg) { + + } + }); + } + + private void changeInfo() { + dataBinding.fullnameEt.setText(loanBean.getFull_name()); + dataBinding.icEt.setText(loanBean.getIc_code()); + dataBinding.phoneNumberEt.setText(loanBean.getPhone()); + dataBinding.occupationEt.setText(loanBean.getOccupation()); + dataBinding.addressEt.setText(loanBean.getAddress()); + dataBinding.beneficiaryBankEt.setText(loanBean.getBank_name()); + dataBinding.beneficiaryAccountNoEt.setText(loanBean.getBank_code()); + dataBinding.salaryEt.setText(loanBean.getSalary()); + dataBinding.loanAmountEt.setText(loanBean.getAmount()); + dataBinding.salaryEt.setText(loanBean.getSalary()); + + Glide.with(XiangQingActivity.this).load(loanBean.getId_front()).placeholder(R.mipmap.sfzzm).error(R.mipmap.sfzzm).into(dataBinding.zhengmianIv); + Glide.with(XiangQingActivity.this).load(loanBean.getId_back()).placeholder(R.mipmap.sfzbm).error(R.mipmap.sfzbm).into(dataBinding.fanmianIv); + + + + dataBinding.statusTv.setTextColor(getResources().getColor(R.color.white)); + if(loanBean.getStatus() == 0){ + dataBinding.statusTv.setText("審批中"); + + }else if(loanBean.getStatus() == 1){ + dataBinding.statusTv.setText("審批成功"); + + }else if(loanBean.getStatus() == 2){ + dataBinding.statusTv.setText("審批失敗"); + dataBinding.statusTv.setTextColor(getResources().getColor(R.color.color_search_2)); + + } + + if(loanBean.getBack_amount()>0){ + dataBinding.huankuanLy.setVisibility(View.VISIBLE); + dataBinding.repaymentAmountEt.setText(String.format("%.2f",loanBean.getBack_amount())); + dataBinding.repaymentStatusEt.setText(loanBean.getIs_back_finish() ==0?"未還清":"還清"); + }else { + dataBinding.huankuanLy.setVisibility(View.GONE); + + } + + } + +} \ No newline at end of file diff --git a/verification/src/main/java/com/dskj/verification/ui/dialog/BankListDialog.java b/verification/src/main/java/com/dskj/verification/ui/dialog/BankListDialog.java new file mode 100644 index 0000000..89ccd7f --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/ui/dialog/BankListDialog.java @@ -0,0 +1,89 @@ +package com.dskj.verification.ui.dialog; + +import android.app.Dialog; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.DisplayMetrics; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ListView; + +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.dskj.verification.R; +import com.dskj.verification.adapter.comm.CommonAdapter; +import com.dskj.verification.adapter.comm.ViewHolder; +import com.dskj.verification.bean.BankBean; +import com.dskj.verification.ui.activity.MainActivity; +import com.dskj.verification.ui.activity.XiangQingActivity; +import com.dskj.verification.viewModel.home.SwitchVideoModel; + +import java.util.List; + +public class BankListDialog extends Dialog { + + private Context mContext; + + private RecyclerView switchDialogList; + + + OnListItemClickListener onNextCallListener; + + private List data; + + public interface OnListItemClickListener { + void onItemClick(BankBean position); + } + public void setOntoAlbumListener(OnListItemClickListener onNextCallListener) { + this.onNextCallListener = onNextCallListener; + } + public BankListDialog(Context context,List data) { + super(context, R.style.dialog_style); + this.mContext = context; + this.data = data; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.bank_dialog); + + switchDialogList = (RecyclerView) findViewById(R.id.switch_dialog_list); + + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext()); + switchDialogList.setLayoutManager(linearLayoutManager); + CommonAdapter commonAdapter = new CommonAdapter(getContext(), R.layout.switch_video_dialog_item, data) { + @Override + public void convert(ViewHolder holder, BankBean s, int index) { + holder.setText(R.id.top_name,s.getName()); + holder.getView(R.id.top_name).setOnClickListener(view -> { + dismiss(); + if(onNextCallListener!=null){ + onNextCallListener.onItemClick(s); + } + }); + } + }; + switchDialogList.setAdapter(commonAdapter); + + Window window = getWindow(); + WindowManager.LayoutParams wlp = window.getAttributes(); + wlp.gravity = Gravity.BOTTOM; + wlp.width = WindowManager.LayoutParams.MATCH_PARENT; + wlp.height = WindowManager.LayoutParams.WRAP_CONTENT; + + + window.setAttributes(wlp); + } + + + + +} diff --git a/verification/src/main/java/com/dskj/verification/ui/dialog/SuccessDialog.java b/verification/src/main/java/com/dskj/verification/ui/dialog/SuccessDialog.java new file mode 100644 index 0000000..36ddcbe --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/ui/dialog/SuccessDialog.java @@ -0,0 +1,75 @@ +package com.dskj.verification.ui.dialog; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.view.Gravity; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.dskj.verification.R; +import com.dskj.verification.adapter.comm.CommonAdapter; +import com.dskj.verification.adapter.comm.ViewHolder; +import com.dskj.verification.bean.BankBean; + +import java.util.List; + +public class SuccessDialog extends Dialog { + + private Context mContext; + + private ImageView jiazaiImg; + private TextView loginBt; + + OnListItemClickListener onNextCallListener; + + private List data; + + public interface OnListItemClickListener { + void onItemClick(); + } + public void setOntoAlbumListener(OnListItemClickListener onNextCallListener) { + this.onNextCallListener = onNextCallListener; + } + public SuccessDialog(Context context) { + super(context, R.style.dialog_style); + this.mContext = context; + this.data = data; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.success_dialog); + + jiazaiImg = (ImageView) findViewById(R.id.jiazai_img); + loginBt = (TextView) findViewById(R.id.login_bt); + Glide.with(getContext()).load(R.mipmap.jinggao_img).into(jiazaiImg); + loginBt.setOnClickListener(v -> { + dismiss(); + if(onNextCallListener!=null){ + onNextCallListener.onItemClick(); + } + }); + Window window = getWindow(); + WindowManager.LayoutParams wlp = window.getAttributes(); + wlp.gravity = Gravity.CENTER; + wlp.width = WindowManager.LayoutParams.WRAP_CONTENT; + wlp.height = WindowManager.LayoutParams.WRAP_CONTENT; + setCancelable(true); + setCanceledOnTouchOutside(true); + + window.setAttributes(wlp); + } + + + + +} diff --git a/verification/src/main/java/com/dskj/verification/ui/dialog/SwitchVideoTypeDialog.java b/verification/src/main/java/com/dskj/verification/ui/dialog/SwitchVideoTypeDialog.java new file mode 100644 index 0000000..0fe0b69 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/ui/dialog/SwitchVideoTypeDialog.java @@ -0,0 +1,76 @@ +package com.dskj.verification.ui.dialog; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.util.DisplayMetrics; +import android.view.LayoutInflater; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ListView; + + +import com.dskj.verification.R; +import com.dskj.verification.viewModel.home.SwitchVideoModel; + +import java.util.List; + +public class SwitchVideoTypeDialog extends Dialog { + + private Context mContext; + + private ListView listView = null; + + private ArrayAdapter adapter = null; + + private OnListItemClickListener onItemClickListener; + + private List data; + + public interface OnListItemClickListener { + void onItemClick(int position); + } + + public SwitchVideoTypeDialog(Context context) { + super(context, R.style.dialog_style); + this.mContext = context; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + public void initList(List data, OnListItemClickListener onItemClickListener) { + this.onItemClickListener = onItemClickListener; + this.data = data; + + LayoutInflater inflater = LayoutInflater.from(mContext); + View view = inflater.inflate(R.layout.switch_video_dialog, null); + listView = (ListView) view.findViewById(R.id.switch_dialog_list); + setContentView(view); + adapter = new ArrayAdapter<>(mContext, R.layout.switch_video_dialog_item, data); + listView.setAdapter(adapter); + listView.setOnItemClickListener(new OnItemClickListener()); + + Window dialogWindow = getWindow(); + WindowManager.LayoutParams lp = dialogWindow.getAttributes(); + DisplayMetrics d = mContext.getResources().getDisplayMetrics(); // 获取屏幕宽、高用 + lp.width = (int) (d.widthPixels * 0.8); // 高度设置为屏幕的0.6 + dialogWindow.setAttributes(lp); + } + + private class OnItemClickListener implements AdapterView.OnItemClickListener { + + @Override + public void onItemClick(AdapterView adapterView, View view, int position, long id) { + dismiss(); + onItemClickListener.onItemClick(position); + } + } + + +} diff --git a/verification/src/main/java/com/dskj/verification/ui/view/BezierCircleHeader.java b/verification/src/main/java/com/dskj/verification/ui/view/BezierCircleHeader.java new file mode 100644 index 0000000..126e7a4 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/ui/view/BezierCircleHeader.java @@ -0,0 +1,364 @@ +package com.dskj.verification.ui.view; + + +import android.animation.ValueAnimator; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.RectF; +import android.util.AttributeSet; +import android.view.View; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; + +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; +import androidx.core.graphics.ColorUtils; + +import com.scwang.smart.refresh.layout.api.RefreshHeader; +import com.scwang.smart.refresh.layout.api.RefreshKernel; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.constant.SpinnerStyle; +import com.scwang.smart.refresh.layout.simple.SimpleComponent; +import com.scwang.smart.refresh.layout.util.SmartUtil; + +/** + * CircleRefresh + * Created by scwang on 2018/7/18. + * from https://github.com/tuesda/CircleRefreshLayout + */ +public class BezierCircleHeader extends SimpleComponent implements RefreshHeader { + + // + protected Path mPath; + protected Paint mBackPaint; + protected Paint mFrontPaint; + protected Paint mOuterPaint; + protected int mHeight; + protected float mWaveHeight; + protected float mHeadHeight; + protected float mSpringRatio; + protected float mFinishRatio; + + protected float mBollY;//弹出球体的Y坐标 + protected float mBollRadius;//球体半径 + protected boolean mShowOuter; + protected boolean mShowBoll;//是否显示中心球体 + protected boolean mShowBollTail;//是否显示球体拖拽的尾巴 + + protected int mRefreshStop = 90; + protected int mRefreshStart = 90; + protected boolean mOuterIsStart = true; + + protected static final int TARGET_DEGREE = 270; + protected boolean mWavePulling = false; + protected RefreshKernel mKernel; + // + + // + public BezierCircleHeader(Context context) { + this(context, null); + } + + public BezierCircleHeader(Context context, AttributeSet attrs) { + super(context, attrs, 0); + + mSpinnerStyle = SpinnerStyle.FixedBehind; + final View thisView = this; + thisView.setMinimumHeight(SmartUtil.dp2px(100)); + mBackPaint = new Paint(); + mBackPaint.setColor(0xff11bbff); + mBackPaint.setAntiAlias(true); + mFrontPaint = new Paint(); + mFrontPaint.setColor(0xffffffff); + mFrontPaint.setAntiAlias(true); + mOuterPaint = new Paint(); + mOuterPaint.setAntiAlias(true); + mOuterPaint.setColor(0xffffffff); + mOuterPaint.setStyle(Paint.Style.STROKE); + mOuterPaint.setStrokeWidth(SmartUtil.dp2px(2f)); + mPath = new Path(); + } + // + + // + @Override + protected void dispatchDraw(Canvas canvas) { + final View thisView = this; + final int viewWidth = thisView.getWidth(); + final int viewHeight = mHeight;//thisView.getHeight(); + //noinspection EqualsBetweenInconvertibleTypes + final boolean footer = mKernel != null && (this.equals(mKernel.getRefreshLayout().getRefreshFooter())); + + if (footer) { + canvas.save(); + canvas.translate(0, thisView.getHeight()); + canvas.scale(1, -1); + } + + if (thisView.isInEditMode()) { + mShowBoll = true; + mShowOuter = true; + mHeadHeight = viewHeight; + mRefreshStop = 270; + mBollY = mHeadHeight / 2; + mBollRadius = mHeadHeight / 6; + } + + drawWave(canvas, viewWidth, viewHeight); + drawSpringUp(canvas, viewWidth); + drawBoll(canvas, viewWidth); + drawOuter(canvas, viewWidth); + drawFinish(canvas, viewWidth); + + if (footer) { + canvas.restore(); + } + + super.dispatchDraw(canvas); + } + + protected void drawWave(Canvas canvas, int viewWidth, int viewHeight) { + float baseHeight = Math.min(mHeadHeight, viewHeight); + if (mWaveHeight != 0) { + mPath.reset(); + mPath.lineTo(viewWidth, 0); + mPath.lineTo(viewWidth, baseHeight); + mPath.quadTo(viewWidth / 2f, baseHeight + mWaveHeight * 2, 0, baseHeight); + mPath.close(); + canvas.drawPath(mPath, mBackPaint); + } else { + canvas.drawRect(0, 0, viewWidth, baseHeight, mBackPaint); + } + } + + protected void drawSpringUp(Canvas canvas, int viewWidth) { + if (mSpringRatio > 0) { + float leftX = (viewWidth / 2f - 4 * mBollRadius + mSpringRatio * 3 * mBollRadius); + if (mSpringRatio < 0.9) { + mPath.reset(); + mPath.moveTo(leftX, mBollY); + mPath.quadTo(viewWidth / 2f, mBollY - mBollRadius * mSpringRatio * 2, + viewWidth - leftX, mBollY); + canvas.drawPath(mPath, mFrontPaint); + } else { + canvas.drawCircle(viewWidth / 2f, mBollY, mBollRadius, mFrontPaint); + } + } + } + + protected void drawBoll(Canvas canvas, int viewWidth) { + if (mShowBoll) { + canvas.drawCircle(viewWidth / 2f, mBollY, mBollRadius, mFrontPaint); + + drawBollTail(canvas, viewWidth, (mHeadHeight + mWaveHeight) / mHeadHeight); + } + } + + protected void drawBollTail(Canvas canvas, int viewWidth, float fraction) { + if (mShowBollTail) { + final float bottom = mHeadHeight + mWaveHeight; + final float startY = mBollY + mBollRadius * fraction / 2; + final float startX = viewWidth / 2f + (float) Math.sqrt(mBollRadius * mBollRadius * (1 - fraction * fraction / 4)); + final float bezier1x = (viewWidth / 2f + (mBollRadius * 3 / 4) * (1 - fraction)); + final float bezier2x = bezier1x + mBollRadius; + + mPath.reset(); + mPath.moveTo(startX, startY); + mPath.quadTo(bezier1x, bottom, bezier2x, bottom); + mPath.lineTo(viewWidth - bezier2x, bottom); + mPath.quadTo(viewWidth - bezier1x, bottom, viewWidth - startX, startY); + canvas.drawPath(mPath, mFrontPaint); + } + } + + protected void drawOuter(Canvas canvas, int viewWidth) { + if (mShowOuter) { + float outerR = mBollRadius + mOuterPaint.getStrokeWidth() * 2; + + mRefreshStart += mOuterIsStart ? 3 : 10; + mRefreshStop += mOuterIsStart ? 10 : 3; + mRefreshStart = mRefreshStart % 360; + mRefreshStop = mRefreshStop % 360; + + int swipe = mRefreshStop - mRefreshStart; + swipe = swipe < 0 ? swipe + 360 : swipe; + + canvas.drawArc(new RectF(viewWidth / 2f - outerR, mBollY - outerR, viewWidth / 2f + outerR, mBollY + outerR), + mRefreshStart, swipe, false, mOuterPaint); + if (swipe >= TARGET_DEGREE) { + mOuterIsStart = false; + } else if (swipe <= 10) { + mOuterIsStart = true; + } + final View thisView = this; + thisView.invalidate(); + } + + } + + protected void drawFinish(Canvas canvas, int viewWidth) { + if (mFinishRatio > 0) { + int beforeColor = mOuterPaint.getColor(); + if (mFinishRatio < 0.3) { + canvas.drawCircle(viewWidth / 2f, mBollY, mBollRadius, mFrontPaint); + int outerR = (int) (mBollRadius + mOuterPaint.getStrokeWidth() * 2 * (1+mFinishRatio / 0.3f)); + int afterColor = ColorUtils.setAlphaComponent(beforeColor, (int) (0xff * (1 - mFinishRatio / 0.3f))); + mOuterPaint.setColor(afterColor); + canvas.drawArc(new RectF(viewWidth / 2f - outerR, mBollY - outerR, viewWidth / 2f + outerR, mBollY + outerR), + 0, 360, false, mOuterPaint); + } + mOuterPaint.setColor(beforeColor); + + if (mFinishRatio >= 0.3 && mFinishRatio < 0.7) { + float fraction = (mFinishRatio - 0.3f) / 0.4f; + mBollY = (int) (mHeadHeight / 2 + (mHeadHeight - mHeadHeight / 2) * fraction); + canvas.drawCircle(viewWidth / 2f, mBollY, mBollRadius, mFrontPaint); + if (mBollY >= mHeadHeight - mBollRadius * 2) { + mShowBollTail = true; + drawBollTail(canvas, viewWidth, fraction); + } + mShowBollTail = false; + } + + if (mFinishRatio >= 0.7 && mFinishRatio <= 1) { + float fraction = (mFinishRatio - 0.7f) / 0.3f; + int leftX = (int) (viewWidth / 2f - mBollRadius - 2 * mBollRadius * fraction); + mPath.reset(); + mPath.moveTo(leftX, mHeadHeight); + mPath.quadTo(viewWidth / 2f, mHeadHeight - (mBollRadius * (1 - fraction)), + viewWidth - leftX, mHeadHeight); + canvas.drawPath(mPath, mFrontPaint); + } + } + } + // + + // + @Override + public void onInitialized(@NonNull RefreshKernel kernel, int height, int maxDragHeight) { + mKernel = kernel; + } + + @Override + public void onMoving(boolean isDragging, float percent, int offset, int height, int maxDragHeight) { + mHeight = offset; + if (isDragging || mWavePulling) { + mWavePulling = true; + mHeadHeight = height; + mWaveHeight = Math.max(offset - height, 0) * .8f; + } + this.invalidate(); + } + + @Override + public void onReleased(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) { + mWavePulling = false; + mHeadHeight = height; + mBollRadius = height / 6f; + DecelerateInterpolator interpolator = new DecelerateInterpolator(); + final float reboundHeight = Math.min(mWaveHeight * 0.8f, mHeadHeight / 2); + ValueAnimator waveAnimator = ValueAnimator.ofFloat( + mWaveHeight, 0, + -(reboundHeight*1.0f),0, + -(reboundHeight*0.4f),0 + ); + waveAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + float speed = 0; + float springBollY; + float springRatio = 0; + int status = 0;//0 还没开始弹起 1 向上弹起 2 在弹起的最高点停住 + @Override + public void onAnimationUpdate(ValueAnimator animation) { + float curValue = (float) animation.getAnimatedValue(); + if (status == 0 && curValue <= 0) { + status = 1; + speed = Math.abs(curValue - mWaveHeight); + } + if (status == 1) { + springRatio = -curValue / reboundHeight; + if (springRatio >= mSpringRatio) { + mSpringRatio = springRatio; + mBollY = mHeadHeight + curValue; + speed = Math.abs(curValue - mWaveHeight); + } else { + status = 2; + mSpringRatio = 0; + mShowBoll = true; + mShowBollTail = true; + springBollY = mBollY; + } + } + if (status == 2) { + if (mBollY > mHeadHeight / 2) { + mBollY = Math.max(mHeadHeight / 2, mBollY - speed); + float bally = animation.getAnimatedFraction() * (mHeadHeight / 2 - springBollY) + springBollY; + if (mBollY > bally) { + mBollY = bally; + } + } + } + if (mShowBollTail && curValue < mWaveHeight) { + mShowOuter = true; + mShowBollTail = false; + mOuterIsStart = true; + mRefreshStart = 90; + mRefreshStop = 90; + } + if (!mWavePulling) { + mWaveHeight = curValue; + final View thisView = BezierCircleHeader.this; + thisView.invalidate(); + } + } + }); + waveAnimator.setInterpolator(interpolator); + waveAnimator.setDuration(1000); + waveAnimator.start(); + } + + @Override + public int onFinish(@NonNull RefreshLayout layout, boolean success) { + mShowBoll = false; + mShowOuter = false; + final int DURATION_FINISH = 800; //动画时长 + ValueAnimator animator = ValueAnimator.ofFloat(0, 1); + animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + final View thisView = BezierCircleHeader.this; + mFinishRatio = (float) animation.getAnimatedValue(); + thisView.invalidate(); + } + }); + animator.setInterpolator(new AccelerateInterpolator()); + animator.setDuration(DURATION_FINISH); + animator.start(); + return DURATION_FINISH; + } + + /** + * @param colors 对应Xml中配置的 srlPrimaryColor srlAccentColor + * @deprecated 只由框架调用 + * 使用者使用 {@link RefreshLayout#setPrimaryColorsId(int...)} + */ + @Override + @Deprecated + public void setPrimaryColors(@ColorInt int ... colors) { + if (colors.length > 0) { + mBackPaint.setColor(colors[0]); + if (colors.length > 1) { + mFrontPaint.setColor(colors[1]); + mOuterPaint.setColor(colors[1]); + } + } + } + +// @NonNull +// @Override +// public SpinnerStyle getSpinnerStyle() { +// return SpinnerStyle.Scale; +// } + // +} diff --git a/verification/src/main/java/com/dskj/verification/ui/view/CircleImageView.java b/verification/src/main/java/com/dskj/verification/ui/view/CircleImageView.java new file mode 100644 index 0000000..a2e6ddb --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/ui/view/CircleImageView.java @@ -0,0 +1,323 @@ +package com.dskj.verification.ui.view; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.RectF; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.MotionEvent; + +import androidx.appcompat.widget.AppCompatImageView; + +import com.dskj.verification.R; + + +public class CircleImageView extends AppCompatImageView { + // paint when user press + private Paint pressPaint; + private int width; + private int height; + + // default bitmap config + private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; + private static final int COLORDRAWABLE_DIMENSION = 1; + + // border color + private int borderColor; + // width of border + private int borderWidth; + // alpha when pressed + private int pressAlpha; + // color when pressed + private int pressColor; + // radius + private int radius; + // rectangle or round, 1 is circle, 2 is rectangle + private int shapeType; + + public CircleImageView(Context context) { + super(context); + init(context, null); + } + + public CircleImageView(Context context, AttributeSet attrs) { + super(context, attrs); + init(context, attrs); + } + + public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs); + } + + + private void init(Context context, AttributeSet attrs) { + //init the value + borderWidth = 0; + borderColor = 0xddffffff; + pressAlpha = 0x42; + pressColor = 0x42000000; + radius = 16; + shapeType = 0; + + // get attribute of EaseImageView + if (attrs != null) { + TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView); + borderColor = array.getColor(R.styleable.CircleImageView_ease_border_color, borderColor); + borderWidth = array.getDimensionPixelOffset(R.styleable.CircleImageView_ease_border_width, borderWidth); + pressAlpha = array.getInteger(R.styleable.CircleImageView_ease_press_alpha, pressAlpha); + pressColor = array.getColor(R.styleable.CircleImageView_ease_press_color, pressColor); + radius = array.getDimensionPixelOffset(R.styleable.CircleImageView_ease_radius, radius); + shapeType = array.getInteger(R.styleable.CircleImageView_es_shape_type, shapeType); + array.recycle(); + } + + // set paint when pressed + pressPaint = new Paint(); + pressPaint.setAntiAlias(true); + pressPaint.setStyle(Paint.Style.FILL); + pressPaint.setColor(pressColor); + pressPaint.setAlpha(0); + pressPaint.setFlags(Paint.ANTI_ALIAS_FLAG); + + setDrawingCacheEnabled(true); + setWillNotDraw(false); + } + + @Override + protected void onDraw(Canvas canvas) { + + if (shapeType == 0) { + super.onDraw(canvas); + return; + } + Drawable drawable = getDrawable(); + if (drawable == null) { + return; + } + // the width and height is in xml file + if (getWidth() == 0 || getHeight() == 0) { + return; + } + Bitmap bitmap = getBitmapFromDrawable(drawable); + drawDrawable(canvas, bitmap); + + if (isClickable()) { + drawPress(canvas); + } + drawBorder(canvas); + } + + /** + * draw Rounded Rectangle + * + * @param canvas + * @param bitmap + */ + @SuppressLint("WrongConstant") + private void drawDrawable(Canvas canvas, Bitmap bitmap) { + Paint paint = new Paint(); + paint.setColor(0xffffffff); + paint.setAntiAlias(true); //smooths out the edges of what is being drawn + PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN); + // set flags + int saveFlags = Canvas.ALL_SAVE_FLAG + ; + canvas.saveLayer(0, 0, width, height, null, saveFlags); + + if (shapeType == 1) { + canvas.drawCircle(width / 2, height / 2, width / 2 - 1, paint); + } else if (shapeType == 2) { + RectF rectf = new RectF(1, 1, getWidth() - 1, getHeight() - 1); + canvas.drawRoundRect(rectf, radius + 1, radius + 1, paint); + } + + paint.setXfermode(xfermode); + + float scaleWidth = ((float) getWidth()) / bitmap.getWidth(); + float scaleHeight = ((float) getHeight()) / bitmap.getHeight(); + + Matrix matrix = new Matrix(); + matrix.postScale(scaleWidth, scaleHeight); + + //bitmap scale + bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); + + canvas.drawBitmap(bitmap, 0, 0, paint); + canvas.restore(); + } + + /** + * draw the effect when pressed + * + * @param canvas + */ + private void drawPress(Canvas canvas) { + // check is rectangle or circle + if (shapeType == 1) { + canvas.drawCircle(width / 2, height / 2, width / 2 - 1, pressPaint); + } else if (shapeType == 2) { + RectF rectF = new RectF(1, 1, width - 1, height - 1); + canvas.drawRoundRect(rectF, radius + 1, radius + 1, pressPaint); + } + } + + /** + * draw customized border + * + * @param canvas + */ + private void drawBorder(Canvas canvas) { + if (borderWidth > 0) { + Paint paint = new Paint(); + paint.setStrokeWidth(borderWidth); + paint.setStyle(Paint.Style.STROKE); + paint.setColor(borderColor); + paint.setAntiAlias(true); + // // check is rectangle or circle + if (shapeType == 1) { + canvas.drawCircle(width / 2, height / 2, (width - borderWidth) / 2, paint); + } else if (shapeType == 2) { + RectF rectf = new RectF(borderWidth / 2, borderWidth / 2, getWidth() - borderWidth / 2, + getHeight() - borderWidth / 2); + canvas.drawRoundRect(rectf, radius, radius, paint); + } + } + } + + /** + * monitor the size change + * + * @param w + * @param h + * @param oldw + * @param oldh + */ + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + width = w; + height = h; + } + + /** + * monitor if touched + * + * @param event + * @return + */ + @Override + public boolean onTouchEvent(MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + pressPaint.setAlpha(pressAlpha); + invalidate(); + break; + case MotionEvent.ACTION_UP: + pressPaint.setAlpha(0); + invalidate(); + break; + case MotionEvent.ACTION_MOVE: + + break; + default: + pressPaint.setAlpha(0); + invalidate(); + break; + } + return super.onTouchEvent(event); + } + + /** + * @param drawable + * @return + */ + private Bitmap getBitmapFromDrawable(Drawable drawable) { + if (drawable == null) { + return null; + } + + if (drawable instanceof BitmapDrawable) { + return ((BitmapDrawable) drawable).getBitmap(); + } + + Bitmap bitmap; + int width = Math.max(drawable.getIntrinsicWidth(), 2); + int height = Math.max(drawable.getIntrinsicHeight(), 2); + try { + bitmap = Bitmap.createBitmap(width, height, BITMAP_CONFIG); + Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); + drawable.draw(canvas); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + bitmap = null; + } + return bitmap; + } + + /** + * set border color + * + * @param borderColor + */ + public void setBorderColor(int borderColor) { + this.borderColor = borderColor; + invalidate(); + } + + /** + * set border width + * + * @param borderWidth + */ + public void setBorderWidth(int borderWidth) { + this.borderWidth = borderWidth; + } + + /** + * set alpha when pressed + * + * @param pressAlpha + */ + public void setPressAlpha(int pressAlpha) { + this.pressAlpha = pressAlpha; + } + + /** + * set color when pressed + * + * @param pressColor + */ + public void setPressColor(int pressColor) { + this.pressColor = pressColor; + } + + /** + * set radius + * + * @param radius + */ + public void setRadius(int radius) { + this.radius = radius; + invalidate(); + } + + /** + * set shape,1 is circle, 2 is rectangle + * + * @param shapeType + */ + public void setShapeType(int shapeType) { + this.shapeType = shapeType; + invalidate(); + } +} diff --git a/verification/src/main/java/com/dskj/verification/ui/view/NestedScrollableHost.java b/verification/src/main/java/com/dskj/verification/ui/view/NestedScrollableHost.java new file mode 100644 index 0000000..b6a6c06 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/ui/view/NestedScrollableHost.java @@ -0,0 +1,145 @@ +package com.dskj.verification.ui.view; + + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.ViewParent; +import android.widget.FrameLayout; + +import java.util.HashMap; + +import androidx.annotation.Nullable; +import androidx.viewpager2.widget.ViewPager2; + +/** + * 此类用于解决 ViewPager2 嵌套 ViewPager2 或者 RecyclerView 等相互嵌套的冲突问题, + */ +public class NestedScrollableHost extends FrameLayout { + + private int touchSlop; + private float initialX; + private float initialY; + private HashMap _$_findViewCache; + + private final ViewPager2 getParentViewPager() { + ViewParent var10000 = this.getParent(); + if (!(var10000 instanceof View)) { + var10000 = null; + } + + View v; + for (v = (View) var10000; v != null && !(v instanceof ViewPager2); v = (View) var10000) { + var10000 = v.getParent(); + if (!(var10000 instanceof View)) { + var10000 = null; + } + } + + View var2 = v; + if (!(v instanceof ViewPager2)) { + var2 = null; + } + + return (ViewPager2) var2; + } + + private final View getChild() { + return this.getChildCount() > 0 ? this.getChildAt(0) : null; + } + + private final boolean canChildScroll(int orientation, float delta) { + boolean var5 = false; + int direction = -((int) Math.signum(delta)); + View var10000; + boolean var6 = false; + switch (orientation) { + case 0: + var10000 = this.getChild(); + var6 = var10000 != null ? var10000.canScrollHorizontally(direction) : false; + break; + case 1: + var10000 = this.getChild(); + var6 = var10000 != null ? var10000.canScrollVertically(direction) : false; + break; + default: + // throw (Throwable)(new IllegalArgumentException()); + } + + return var6; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent e) { + this.handleInterceptTouchEvent(e); + return super.onInterceptTouchEvent(e); + } + + private final void handleInterceptTouchEvent(MotionEvent e) { + ViewPager2 var10000 = this.getParentViewPager(); + if (var10000 != null) { + int orientation = var10000.getOrientation(); + if (this.canChildScroll(orientation, -1.0F) || this.canChildScroll(orientation, 1.0F)) { + if (e.getAction() == 0) { + this.initialX = e.getX(); + this.initialY = e.getY(); + this.getParent().requestDisallowInterceptTouchEvent(true); + } else if (e.getAction() == 2) { + float dx = e.getX() - this.initialX; + float dy = e.getY() - this.initialY; + boolean isVpHorizontal = orientation == 0; + boolean var8 = false; + float scaledDx = Math.abs(dx) * (isVpHorizontal ? 0.5F : 1.0F); + boolean var9 = false; + float scaledDy = Math.abs(dy) * (isVpHorizontal ? 1.0F : 0.5F); + if (scaledDx > (float) this.touchSlop || scaledDy > (float) this.touchSlop) { + if (isVpHorizontal == scaledDy > scaledDx) { + this.getParent().requestDisallowInterceptTouchEvent(false); + } else if (this.canChildScroll(orientation, isVpHorizontal ? dx : dy)) { + this.getParent().requestDisallowInterceptTouchEvent(true); + } else { + this.getParent().requestDisallowInterceptTouchEvent(false); + } + } + } + + } + } + } + + public NestedScrollableHost(Context context) { + super(context); + ViewConfiguration var10001 = ViewConfiguration.get(this.getContext()); + this.touchSlop = var10001.getScaledTouchSlop(); + } + + public NestedScrollableHost(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + ViewConfiguration var10001 = ViewConfiguration.get(this.getContext()); + this.touchSlop = var10001.getScaledTouchSlop(); + } + + public View _$_findCachedViewById(int var1) { + if (this._$_findViewCache == null) { + this._$_findViewCache = new HashMap(); + } + + View var2 = (View) this._$_findViewCache.get(var1); + if (var2 == null) { + var2 = this.findViewById(var1); + this._$_findViewCache.put(var1, var2); + } + + return var2; + } + + public void _$_clearFindViewByIdCache() { + if (this._$_findViewCache != null) { + this._$_findViewCache.clear(); + } + + } +} + diff --git a/verification/src/main/java/com/dskj/verification/ui/view/StatusLayout.java b/verification/src/main/java/com/dskj/verification/ui/view/StatusLayout.java new file mode 100644 index 0000000..3b24137 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/ui/view/StatusLayout.java @@ -0,0 +1,44 @@ +package com.dskj.verification.ui.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.ViewGroup; +import android.widget.LinearLayout; + +import androidx.annotation.Nullable; + +/** + * Created by kiun_2007 on 2018/3/29. + */ + +public class StatusLayout extends LinearLayout { + public StatusLayout(Context context) { + this(context, null); + } + + public StatusLayout(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public StatusLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + private int getStatusBarHeight(Context context) { + int result = 0; + int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (resourceId > 0) { + result = context.getResources().getDimensionPixelSize(resourceId); + } + return result; + } + + @Override + protected void onAttachedToWindow() { + ViewGroup.LayoutParams lp = this.getLayoutParams(); + lp.width = -1; + lp.height = getStatusBarHeight(getContext()); + this.setLayoutParams(lp); + super.onAttachedToWindow(); + } +} diff --git a/verification/src/main/java/com/dskj/verification/utils/AppContextUtil.java b/verification/src/main/java/com/dskj/verification/utils/AppContextUtil.java new file mode 100644 index 0000000..197c8a5 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/utils/AppContextUtil.java @@ -0,0 +1,22 @@ +package com.dskj.verification.utils; + +import android.content.Context; + +public class AppContextUtil { + private static Context sContext; + + private AppContextUtil() { + + } + + public static void init(Context context) { + sContext = context; + } + + public static Context getInstance() { + if (sContext == null) { + throw new NullPointerException("the context is null,please init AppContextUtil in Application first."); + } + return sContext; + } +} diff --git a/verification/src/main/java/com/dskj/verification/utils/CenterAlignImageSpan.java b/verification/src/main/java/com/dskj/verification/utils/CenterAlignImageSpan.java new file mode 100644 index 0000000..18c2036 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/utils/CenterAlignImageSpan.java @@ -0,0 +1,33 @@ +package com.dskj.verification.utils; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.drawable.Drawable; +import android.text.style.ImageSpan; + +import androidx.annotation.NonNull; + +public class CenterAlignImageSpan extends ImageSpan { + public CenterAlignImageSpan(Drawable drawable) { + super(drawable); + + } + + public CenterAlignImageSpan(Bitmap b) { + super(b); + } + + @Override + public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, + @NonNull Paint paint) { + + Drawable b = getDrawable(); + Paint.FontMetricsInt fm = paint.getFontMetricsInt(); + int transY = (y + fm.descent + y + fm.ascent) / 2 - b.getBounds().bottom / 2;//计算y方向的位移 + canvas.save(); + canvas.translate(x, transY);//绘制图片位移一段距离 + b.draw(canvas); + canvas.restore(); + } +} diff --git a/verification/src/main/java/com/dskj/verification/utils/DeviceUtil.java b/verification/src/main/java/com/dskj/verification/utils/DeviceUtil.java new file mode 100644 index 0000000..84fcc84 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/utils/DeviceUtil.java @@ -0,0 +1,83 @@ +package com.dskj.verification.utils; + +import android.content.Context; +import android.os.Environment; +import android.os.StatFs; +import android.util.DisplayMetrics; +import android.view.Display; +import android.view.WindowManager; + +import java.io.File; + + +public final class DeviceUtil { + + public static int SCREEN_WIDTH; + public static int SCREEN_HEIGHT; + + public static float DENSITY; + public static float DENSITY_SCALE; + public static int DENSITY_DPI; + + public static void init(Context context) { + if (null == context) return; + DisplayMetrics displayMetrics = new DisplayMetrics(); + WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + windowManager.getDefaultDisplay().getRealMetrics(displayMetrics); + SCREEN_WIDTH = displayMetrics.widthPixels; + SCREEN_HEIGHT = displayMetrics.heightPixels; + DENSITY = displayMetrics.density; + DENSITY_SCALE = displayMetrics.scaledDensity; + DENSITY_DPI = displayMetrics.densityDpi; + } + + public static int dip2px(float dip) { + return (int) (dip * DENSITY + 0.5F); + } + + public static boolean isStorageEnough(Context context, long minSize) { + try { + File path = Environment.getExternalStorageDirectory(); + StatFs stat = new StatFs(path.toString()); + long blocksize = stat.getBlockSizeLong(); + long availbleblocks = stat.getAvailableBlocksLong(); + long avilableSize = availbleblocks * blocksize; + return avilableSize >= minSize; + }catch (Exception e){ + e.printStackTrace(); + } + return false; + } + + + + /** + * 根据手机的分辨率从 px(像素) 的单位 转成为 dp + * @param context 上下文 + * @param pxValue px值 + * @return dp值 + */ + public static int px2dip(Context context, float pxValue) { + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (pxValue / scale + 0.5f); + } + + /** + * 获取当前的屏幕尺寸 + * + * @param context {@link Context} + * @return 屏幕尺寸 + */ + public static int[] getScreenSize(Context context) { + int[] size = new int[2]; + + WindowManager w = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + Display d = w.getDefaultDisplay(); + DisplayMetrics metrics = new DisplayMetrics(); + d.getMetrics(metrics); + + size[0] = metrics.widthPixels; + size[1] = metrics.heightPixels; + return size; + } +} diff --git a/verification/src/main/java/com/dskj/verification/utils/FileUtils.java b/verification/src/main/java/com/dskj/verification/utils/FileUtils.java new file mode 100644 index 0000000..36a096c --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/utils/FileUtils.java @@ -0,0 +1,905 @@ +package com.dskj.verification.utils; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.PixelFormat; +import android.graphics.drawable.Drawable; +import android.media.MediaScannerConnection; +import android.net.Uri; +import android.os.Environment; +import android.os.StatFs; +import android.provider.MediaStore; +import android.text.TextUtils; +import android.util.Log; +import com.dskj.verification.InitApp; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.RandomAccessFile; +import java.io.UnsupportedEncodingException; +import java.nio.channels.FileChannel; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.List; + +public class FileUtils { + public static String APP_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "bkwatermark" + File.separator; + public static String THUMBNAIL_DIR = APP_DIR + ".thumbnailrecord" + File.separator; + public static String TEMP_DIR = APP_DIR + "temprecord" + File.separator; + //以下三个不能清理 + public static String IMAGE_DIR = APP_DIR + "tempimage" + File.separator; + public static String VIDEO_DIR = APP_DIR + "recordvideo" + File.separator; + public static String THUMB_DIR = APP_DIR + ".videothumb" + File.separator; + public static String CAPTURER_DIR = APP_DIR + "recordscreen" + File.separator; + //以上三个不能清理 + //以下的 结尾的两个mp4文件和ts文件不能清理 + public static String VIDEO_DIR_HIDE = APP_DIR + ".recordvideo" + File.separator; + + /** + * 从assets目录中复制整个文件夹内容到新的路径下 + * @param context Context 使用CopyFiles类的Activity + * @param oldPath String 原文件路径 如:Data(assets文件夹下文件夹名称) + * @param newPath String 复制后路径 如:data/data/(手机内部存储路径名称) + */ + public void copyFilesFromAssets(Context context,String oldPath,String newPath) { + try { + InputStream is = context.getAssets().open(oldPath); + FileOutputStream fos = new FileOutputStream(new File(newPath)); + byte[] buffer = new byte[1024]; + int byteCount=0; + while((byteCount=is.read(buffer))!=-1) {//循环从输入流读取 buffer字节 + fos.write(buffer, 0, byteCount);//将读取的输入流写入到输出流 + } + fos.flush();//刷新缓冲区 + is.close(); + fos.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static String getFileNameNoEx(String filename) { + if ((filename != null) && (filename.length() > 0)) { + int dot = filename.lastIndexOf('.'); + if ((dot > -1) && (dot < (filename.length()))) { + return filename.substring(0, dot); + } + } + return filename; + } + + public static Uri getVideoContentUri(Context context, String path) { + Uri uri = null; + Cursor cursor = context.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, + new String[]{MediaStore.Video.Media._ID}, MediaStore.Video.Media.DATA + "=? ", + new String[]{path}, null); + + if (cursor != null) { + if (cursor.moveToFirst()) { + int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID)); + Uri baseUri = Uri.parse("content://media/external/video/media"); + uri = Uri.withAppendedPath(baseUri, "" + id); + } + + cursor.close(); + } + + if (uri == null) { + ContentValues values = new ContentValues(); + values.put(MediaStore.Video.Media.DATA, path); + uri = context.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values); + } + + return uri; + } + + + public static long getAvilableSize(){ + File path = Environment.getExternalStorageDirectory(); + StatFs stat = new StatFs(path.toString()); + long blocksize = stat.getBlockSizeLong(); + long availbleblocks = stat.getAvailableBlocksLong(); + long avilableSize = availbleblocks * blocksize; + return avilableSize; + } + + public static long getDirectorySize(File directory) { + final File[] files = directory.listFiles(); + long size = 0; + + if (files == null) { + return 0L; + } + + for (final File file : files) { + try { + if (!isSymlink(file)) { + size += sizeOf(file); + if (size < 0) { + break; + } + } + } catch (IOException ioe) { + // ignore exception when asking for symlink + } + } + + return size; + } + /** + * 检测文件是否可用 + */ + public static boolean checkFile(String path) { + if (!TextUtils.isEmpty(path)) { + File f = new File(path); + if (f != null && f.exists() && f.canRead() && (f.isDirectory() || (f.isFile() + && f.length() > 0))) { + return true; + } + } + return false; + } + + public static String getExtension(String name) { + String ext; + + if (name.lastIndexOf(".") == -1) { + ext = ""; + + } else { + int index = name.lastIndexOf("."); + ext = name.substring(index + 1, name.length()); + } + return ext; + } + + private static boolean isSymlink(File file) throws IOException { + File fileInCanonicalDir; + + if (file.getParent() == null) { + fileInCanonicalDir = file; + } else { + File canonicalDir = file.getParentFile().getCanonicalFile(); + fileInCanonicalDir = new File(canonicalDir, file.getName()); + } + + return !fileInCanonicalDir.getCanonicalFile().equals(fileInCanonicalDir.getAbsoluteFile()); + } + + + + public static String getFileName(String path) { + String s[] = path.split("/"); + if (s.length != 0) + return "/" + s[s.length - 1]; + return "/"; + } + /** + * Return the name of file. + * + * @param file The file. + * @return the name of file + */ + public static String getFileName(final File file) { + if (file == null) return ""; + return getFileName(file.getAbsolutePath()); + } + + private static long sizeOf(File file) { + if (file.isDirectory()) { + return getDirectorySize(file); + } else { + return file.length(); + } + } + + + public static void writeTxtToFile(List strcontent, String filePath, String fileName) { + makeFilePath(filePath, fileName); + String strFilePath = filePath + fileName; + String strContent = ""; + + for (int i = 0; i < strcontent.size(); ++i) { + strContent = strContent + "file " + strcontent.get(i) + "\r\n"; + } + + try { + File file = new File(strFilePath); + if (file.isFile() && file.exists()) { + file.delete(); + } + + file.getParentFile().mkdirs(); + file.createNewFile(); + RandomAccessFile raf = new RandomAccessFile(file, "rwd"); + raf.seek(file.length()); + raf.write(strContent.getBytes()); + raf.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + public static boolean saveBitmap(Bitmap src, String dest) { + if (src == null || TextUtils.isEmpty(dest)) { + return false; + } + File destDir = new File(dest).getParentFile(); + if (destDir == null) { + return false; + } + if (!destDir.exists()) { + destDir.mkdirs(); + } + + FileOutputStream fout = null; + boolean success = false; + try { + fout = new FileOutputStream(dest); + src.compress(Bitmap.CompressFormat.PNG, 100, fout); + + success = true; + } catch (FileNotFoundException e) { + e.printStackTrace(); + success = false; + } finally { + if (fout != null) { + try { + fout.close(); + } catch (IOException e) { + e.printStackTrace(); + success = false; + } + } + return success; + } + } + + public static boolean saveBitmapPic(Context context,Bitmap src, String dest,String fileName) { + if (src == null || TextUtils.isEmpty(dest)) { + return false; + } + File destDir = new File(dest).getParentFile(); + if (destDir == null) { + return false; + } + if (!destDir.exists()) { + destDir.mkdirs(); + } + + FileOutputStream fout = null; + boolean success = false; + try { + fout = new FileOutputStream(dest); + src.compress(Bitmap.CompressFormat.PNG, 100, fout); + + + success = true; + } catch (FileNotFoundException e) { + e.printStackTrace(); + success = false; + } finally { + if (fout != null) { + try { + fout.close(); + } catch (IOException e) { + e.printStackTrace(); + success = false; + } + } + // 其次把文件插入到系统图库 + try { + MediaStore.Images.Media.insertImage(context.getContentResolver(), + dest, fileName, null); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + return success; + } + } + + + public static String saveBitmap2Gallery(String dest,String fileName, Bitmap bitmap) { + File mPicDir = new File(dest); + + if (mPicDir == null) { + return null; + } + if (!mPicDir.exists()) { + mPicDir.mkdirs(); + } + OutputStream out = null; + String[] pathArray = null; + String[] typeArray = null; + String fialeN=null; + try { + // Android 10版本 创建文件夹不成功,这里没有过多去研究 + boolean isMk = mPicDir.mkdirs(); + Log.d("ImageUtils ", "isMk = " + isMk); + File mPicFile = new File(mPicDir, fileName); + String mPicPath = mPicFile.getAbsolutePath(); + Log.d("ImageUtils ", "mPicPath = " + mPicPath); + pathArray = new String[]{mPicFile.getAbsolutePath()}; + typeArray = new String[]{"image/png"}; + ContentValues values = new ContentValues(); + ContentResolver resolver = InitApp.initApp.getContentResolver(); + values.put(MediaStore.Images.ImageColumns.DATA, mPicPath); + values.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, fileName); + values.put(MediaStore.Images.ImageColumns.MIME_TYPE, "image/png"); + values.put(MediaStore.Images.ImageColumns.DATE_TAKEN, System.currentTimeMillis() + ""); + // 插入相册 + Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); + if (uri != null) { + out = resolver.openOutputStream(uri); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); + Log.d("ImageUtils ", "compress"); + } + fialeN=fileName; + } catch (Exception e) { + e.printStackTrace(); + fialeN=null; + } finally { + if (out != null) { + try { + out.flush(); + out.close(); + Log.d("ImageUtils", "finally close"); + // 扫描刷新 + MediaScannerConnection.scanFile(InitApp.initApp, pathArray, typeArray, (s, uri) -> Log.d("ImageUtils", "onScanCompleted s->" + s)); + return fialeN; + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return fialeN; + } + + + public static File makeFilePath(String filePath, String fileName) { + File file = null; + makeRootDirectory(filePath); + + try { + file = new File(filePath + fileName); + if (!file.exists()) { + file.createNewFile(); + } + } catch (Exception e) { + e.printStackTrace(); + } + + return file; + } + + public static void makeRootDirectory(String filePath) { + File file = null; + + try { + file = new File(filePath); + if (!file.exists()) { + file.mkdirs(); + } + } catch (Exception e) { + Log.i("error:", e + ""); + } + } + + /** + * 递归删除文件和文件夹 + * + * @param file + */ + public static void deleteFileRecursively(File file) { + if (file.isFile()) { + file.delete(); + return; + } + if (file.isDirectory()) { + File[] childFile = file.listFiles(); + if (childFile == null || childFile.length == 0) { + file.delete(); + return; + } + for (File f : childFile) { + deleteFileRecursively(f); + } + file.delete(); + } + } + + public static String md5(String content) { + byte[] hash; + try { + hash = MessageDigest.getInstance("MD5").digest(content.getBytes("UTF-8")); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("NoSuchAlgorithmException", e); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("UnsupportedEncodingException", e); + } + + StringBuilder hex = new StringBuilder(hash.length * 2); + for (byte b : hash) { + if ((b & 0xFF) < 0x10) { + hex.append("0"); + } + hex.append(Integer.toHexString(b & 0xFF)); + } + return hex.toString(); + } + + public static String getSaveUpdateDirectory() { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + String rootDir = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "SuperRecord" + File.separator + "update" + File.separator; + File file = new File(rootDir); + if (!file.exists()) { + if (!file.mkdirs()) { + return null; + } + } + return rootDir; + } else { + return null; + } + } + + + /** + * check the usability of the external storage. + * + * @return enable -> true, disable->false + */ + public static boolean isExternalStorageEnable() { + String state = Environment.getExternalStorageState(); + return Environment.MEDIA_MOUNTED.equals(state); + } + + /** + * get the external storage file path + * + * @return the file path + */ + public static String getExternalStoragePath() { + return getExternalStorageDir().getAbsolutePath(); + } + + /** + * get the external storage file + * + * @return the file + */ + public static File getExternalStorageDir() { + return Environment.getExternalStorageDirectory(); + } + + public static String handleSpaceFilePath(String path) { + if (TextUtils.isEmpty(path) || !path.contains(" ")) { + return path; + } + + File origin = new File(path); + String fileName = origin.getName(); + if (fileName.contains(" ")) { + fileName = fileName.replaceAll(" ", ""); + } + + File targetDir = new File(TEMP_DIR); + if (!targetDir.exists()) { + targetDir.mkdirs(); + } + + File after = new File(targetDir, fileName); + copyFile(origin, after); + return after.getAbsolutePath(); + } + + + public static boolean copyFile(File src, File dest) { + if (src == null || dest == null) { + return false; + } + if (dest.exists()) { + return true; + } + + if (TextUtils.equals(src.getParent(), dest.getParent())) { + return src.renameTo(dest); + } + + try { + dest.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + + FileChannel srcChannel = null; + FileChannel dstChannel = null; + + boolean result = false; + try { + srcChannel = new FileInputStream(src).getChannel(); + dstChannel = new FileOutputStream(dest).getChannel(); + srcChannel.transferTo(0, srcChannel.size(), dstChannel); + result = true; + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + srcChannel.close(); + dstChannel.close(); + } catch (Exception e) { + e.printStackTrace(); + result = false; + } + } + return result; + } + + public static String getTempDirectory() { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + File file = new File(TEMP_DIR); + if (!file.exists()) { + if (!file.mkdirs()) { + return null; + } + } + return TEMP_DIR; + } else { + return null; + } + } + + public static String getSaveRecordDirectory() { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + File file = new File(VIDEO_DIR); + if (!file.exists()) { + if (!file.mkdirs()) { + return null; + } + } + return VIDEO_DIR; + } else { + return null; + } + } + + public static String getSaveRecordPicDirectory() { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + File file = new File(THUMB_DIR); + if (!file.exists()) { + if (!file.mkdirs()) { + return null; + } + } + return THUMB_DIR; + } else { + return null; + } + } + + + public static String getSaveCacheDirectory() { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + String rootDir = Environment.getExternalStorageDirectory().getAbsolutePath() + + File.separator + "ScreenRecord" + + File.separator + "cache" + + File.separator + "frame" + File.separator; + File file = new File(rootDir); + if (file.exists()) { + deleteDir(rootDir); + } + file.mkdirs(); + return rootDir; + } else { + return null; + } + } + + public static String getSaveCoverDirectory() { + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + String rootDir = Environment.getExternalStorageDirectory().getAbsolutePath() + + File.separator + "ScreenRecord" + + File.separator + "cache" + + File.separator + "cover" + File.separator; + File file = new File(rootDir); + if (!file.exists()) { + file.mkdirs(); + } + return rootDir; + } else { + return null; + } + } + + public static String getSaveScreenDirectory() { +// if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + File file = new File(CAPTURER_DIR); + if (!file.exists()) { + if (!file.mkdirs()) { + return null; + } + } + return CAPTURER_DIR; +// } else { +// return null; +// } + } + + public static void deleteDir(final String pPath) { + File dir = new File(pPath); + deleteDirWithFile(dir); + } + + public static void deleteDirWithFile(File dir) { + if (dir == null || !dir.exists() || !dir.isDirectory()) + return; + for (File file : dir.listFiles()) { + if (file.isFile()) + file.delete(); + else if (file.isDirectory()) + deleteDirWithFile(file); + } + dir.delete(); + } + + public static boolean fileIsExist(String filePath) { + if (TextUtils.isEmpty(filePath)) return false; + + File file = new File(filePath); + return file.exists(); + } + + + public static void deleteFile(String path) { + if (TextUtils.isEmpty(path)) { + return; + } + File file = new File(path); + Log.i("XHXDEBUG","XHXDEBUG清理删除文件:"+path); + if (file.exists() && file.isFile()) { + file.delete(); + } + } + + public static boolean isExists(String path) { + if (TextUtils.isEmpty(path)) { + return false; + } + + File file = new File(path); + return file.exists(); + } + + + public static Uri getImageContentUri(Context context, String filePath) { + Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + new String[]{MediaStore.Images.Media._ID}, MediaStore.Images.Media.DATA + "=? ", + new String[]{filePath}, null); + Uri uri = null; + + if (cursor != null) { + if (cursor.moveToFirst()) { + int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID)); + Uri baseUri = Uri.parse("content://media/external/images/media"); + uri = Uri.withAppendedPath(baseUri, "" + id); + } + + cursor.close(); + } + + if (uri == null) { + ContentValues values = new ContentValues(); + values.put(MediaStore.Images.Media.DATA, filePath); + uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); + } + + return uri; + } + + //存储assets中的文件到本地 + public static void getAssetsPath(Context context) { + String fileName = "ic_share_image.jpeg"; + File testFolder = new File(APP_DIR + "/share"); + if (testFolder.exists() && testFolder.isDirectory()) { + Log.d("", "test folder already exists"); + } else if (!testFolder.exists()) { + testFolder.mkdir(); + } + File modelFile = new File(testFolder, fileName); + if (!modelFile.exists()) { + new Thread(new Runnable() { + @Override + public void run() { + try { + InputStream is = context.getAssets().open(fileName); + FileOutputStream fos = new FileOutputStream(modelFile); + byte[] buffer = new byte[8192]; + int read; + try { + while ((read = is.read(buffer)) != -1) { + fos.write(buffer, 0, read); + } + } finally { + fos.flush(); + fos.close(); + is.close(); + } + } catch (IOException e) { + Log.d("", "Can't copy test file onto SD card"); + } + } + }).start(); + } + } + + public static int saveImageToGalleryShare(Context mContext, Bitmap bmp, String fileName) { + //生成路径 + String root = APP_DIR; + String dirName = "tempimage"; + File appDir = new File(root, dirName); + if (!appDir.exists()) { + appDir.mkdirs(); + } + //获取文件 + File file = new File(appDir, fileName); + FileOutputStream fos = null; + try { + fos = new FileOutputStream(file); + bmp.compress(Bitmap.CompressFormat.PNG, 100, fos); + fos.flush(); + //通知系统相册刷新 +// mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, +// Uri.fromFile(new File(file.getPath())))); + //通知更新相册 + mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file))); + + return 2; + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (fos != null) { + fos.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return -1; + } + + /** + * Drawable转换成一个Bitmap + * + * @param drawable drawable对象 + * @return + */ + public static Bitmap drawableToBitmap(Drawable drawable) { + Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), + drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); + Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); + drawable.draw(canvas); + return bitmap; + } + + + /** + * oldPath 和 newPath必须是新旧文件的绝对路径 + */ + public static File renameFile(String oldPath, String newPath) { + if (TextUtils.isEmpty(oldPath)) { + return null; + } + + if (TextUtils.isEmpty(newPath)) { + return null; + } + File oldFile = new File(oldPath); + File newFile = new File(newPath); + boolean b = oldFile.renameTo(newFile); + File file2 = new File(newPath); + return file2; + } + + /** + * 删除单个文件 + * + * @param filePath$Name 要删除的文件的文件名 + * @return 单个文件删除成功返回true,否则返回false + */ + public static boolean deleteSingleFile(String filePath$Name) { + File file = new File(filePath$Name); + // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除 + if (file.exists() && file.isFile()) { + if (file.delete()) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + /** + * 复制asset到片尾 + */ + public static boolean copyAssetsToDst(Context context, String srcPath) { + File targetDir0 = new File(APP_DIR); + if (!targetDir0.exists()) { + targetDir0.mkdirs(); + } + + File targetDir = new File(VIDEO_DIR_HIDE); + if (!targetDir.exists()) { + targetDir.mkdirs(); + } + + try { + File outFile = new File(VIDEO_DIR_HIDE, srcPath); + InputStream is = context.getAssets().open(srcPath); + FileOutputStream fos = new FileOutputStream(outFile); + byte[] buffer = new byte[1024]; + int byteCount; + while ((byteCount = is.read(buffer)) != -1) { + fos.write(buffer, 0, byteCount); + } + fos.flush(); + is.close(); + fos.close(); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + + /**读取assets文件*/ + public static String getFromAssets(Context context,String fileName) { + try { + InputStreamReader inputReader = new InputStreamReader(context.getResources().getAssets().open(fileName)); + BufferedReader bufReader = new BufferedReader(inputReader); + String line = ""; + String Result = ""; + while ((line = bufReader.readLine()) != null) + Result += line; + return Result; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + + } + + + /* + * Java文件操作 获取文件扩展名 + * + */ + public static String getExtensionName(String filename) { + if ((filename != null) && (filename.length() > 0)) { + int dot = filename.lastIndexOf('.'); + if ((dot >-1) && (dot < (filename.length() - 1))) { + return filename.substring(dot + 1); + } + } + return filename; + } +} diff --git a/verification/src/main/java/com/dskj/verification/utils/GetAndroidUniqueMark.java b/verification/src/main/java/com/dskj/verification/utils/GetAndroidUniqueMark.java new file mode 100644 index 0000000..9098c2c --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/utils/GetAndroidUniqueMark.java @@ -0,0 +1,54 @@ +package com.dskj.verification.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.os.Build; +import android.provider.Settings; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * 设备码的一些东西 + * @author + */ + +public class GetAndroidUniqueMark { + + public static String getUniqueId(Context context) { + @SuppressLint("HardwareIds") + // ANDROID_ID是设备第一次启动时产生和存储的64bit的一个数,当设备被wipe后该数重置。 + String androidID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); + @SuppressLint("HardwareIds") + String id = androidID + Build.SERIAL; // +硬件序列号 + try { + return toMD5(id); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + return id; + } + } + + public static String toMD5(String text) throws NoSuchAlgorithmException { + //获取摘要器 MessageDigest + MessageDigest messageDigest = MessageDigest.getInstance("MD5"); + //通过摘要器对字符串的二进制字节数组进行hash计算 + byte[] digest = messageDigest.digest(text.getBytes()); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < digest.length; i++) { + //循环每个字符 将计算结果转化为正整数; + int digestInt = digest[i] & 0xff; + //将10进制转化为较短的16进制 + String hexString = Integer.toHexString(digestInt); + //转化结果如果是个位数会省略0,因此判断并补0 + if (hexString.length() < 2) { + sb.append(0); + } + //将循环结果添加到缓冲区 + sb.append(hexString); + } + //返回整个结果 + return sb.toString().substring(8, 24); + } + +} diff --git a/verification/src/main/java/com/dskj/verification/utils/GsonUtils.java b/verification/src/main/java/com/dskj/verification/utils/GsonUtils.java new file mode 100644 index 0000000..7b419c0 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/utils/GsonUtils.java @@ -0,0 +1,90 @@ +package com.dskj.verification.utils; + +import android.text.TextUtils; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +/** + * json解析工具类 其实对于数组解析有一些问题 + * @author xuhuixiang + */ +public class GsonUtils { + + public static Gson gson = new Gson(); + + /** + * 返回List对象 + * @param str + * @param type new TypeToken>(){}.getType() + * @param + * @return + */ + public static T getListFromJSON(String str, Type type) { + if (!TextUtils.isEmpty(str)) { + return gson.fromJson(str, type); + } + return null; + } + + /** + * 返回List对象 + * @param str + * @param cls + * @param + * @return + */ + public static List getListFromJSON(String str, Class cls) + { + Type type = new TypeToken>() + {}.getType(); + ArrayList jsonObjects = gson.fromJson(str, type); + ArrayList arrayList = new ArrayList<>(); + for (JsonObject jsonObject : jsonObjects) + { + arrayList.add(gson.fromJson(jsonObject, cls)); + } + return arrayList; + } + + /** + * 返回对象 + * @param str + * @param cls + * @param + * @return + */ + public static T getObjFromJSON(String str, Class cls) { +// try { + if (!TextUtils.isEmpty(str)) { + return gson.fromJson(str, cls); + } + return null; +// }catch (Exception e) { +// return null; +// } + } + + /** + * 返回JsonString + * @return + */ + public static String beanToJSONString(Object bean) { + return new Gson().toJson(bean); + } + + + public static String JSONTokener(String in) { + // consume an optional byte order mark (BOM) if it exists + if (in != null && in.startsWith("\ufeff")) { + in = in.substring(1); + } + return in; + } + +} diff --git a/verification/src/main/java/com/dskj/verification/utils/LogUtils.java b/verification/src/main/java/com/dskj/verification/utils/LogUtils.java new file mode 100644 index 0000000..c42560a --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/utils/LogUtils.java @@ -0,0 +1,146 @@ +package com.dskj.verification.utils; + +import android.util.Log; + + + +/** + * Log统一管理类 + * Created by xuhuixiang on 2015/10/19 0019. + */ +public class LogUtils { + + private LogUtils() { + throw new UnsupportedOperationException("cannot be instantiated"); + } + +// public static boolean isDebug = ApiService.isDebug;// 是否需要打印bug,可以在application的onCreate函数里面初始化 + public static boolean isDebug = true;// 是否需要打印bug,可以在application的onCreate函数里面初始化 + + private static final String TAG = "BIKAOVIDEO"; + + /** + * 默认tag的函数 + * + * @param msg 打印信息 + */ + public static void v(String msg) { + if (isDebug) Log.v(TAG, msg); + } + + public static void d(String msg) { + if (isDebug) Log.d(TAG, msg); + } + + public static void i(String msg) { + if (isDebug) { + if (msg.length() > 4000) { + Log.i(TAG, "BIKAOVIDEOsb.length = " + msg.length()); + int chunkCount = msg.length() / 4000; // integer division + for (int i = 0; i <= chunkCount; i++) { + int max = 4000 * (i + 1); + if (max >= msg.length()) { + Log.i(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i)); + } else { + Log.i(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i, max)); + } + } + } else { + Log.i(TAG, "BIKAOVIDEO" + msg.toString()); + } + } + } + + public static void w(String msg) { + if (isDebug) Log.w(TAG, msg); + } + + public static void e(String msg) { + if (isDebug) { + if (msg.length() > 4000) { + Log.e(TAG, "sb.length = " + msg.length()); + int chunkCount = msg.length() / 4000; // integer division + for (int i = 0; i <= chunkCount; i++) { + int max = 4000 * (i + 1); + if (max >= msg.length()) { + Log.e(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i)); + } else { + Log.e(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i, max)); + } + } + } else { + Log.e(TAG, "XHX" + msg.toString()); + } + + } + + } + + /** + * 自定义lag的函数 + * + * @param tag tag + * @param msg 打印信息 + */ + public static void v(String tag, String msg) { + if (isDebug) Log.v(tag, msg); + } + + public static void d(String tag, String msg) { + if (isDebug) Log.d(tag, msg); + } + + public static void i(String tag, String msg) { + if (isDebug) { + if (msg.length() > 4000) { + Log.i(TAG, "sb.length = " + msg.length()); + int chunkCount = msg.length() / 4000; // integer division + for (int i = 0; i <= chunkCount; i++) { + int max = 4000 * (i + 1); + if (max >= msg.length()) { + Log.i(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i)); + } else { + Log.i(TAG, "XHXchunk " + i + " of " + chunkCount + ":" + msg.substring(4000 * i, max)); + } + } + } else { + Log.i(TAG, "XHX" + msg.toString()); + } + } + } + + public static void w(String tag, String msg) { + if (isDebug) Log.w(tag, msg); + } + + public static void e(String tag, String msg) { + if (isDebug) Log.e(tag, msg); + } + + /** + * 自定义lag的函数 + * + * @param clazz 类 + * @param msg 打印信息 + */ + public static void v(Class clazz, String msg) { + if (isDebug) Log.v(clazz.getSimpleName(), msg); + } + + public static void d(Class clazz, String msg) { + if (isDebug) Log.d(clazz.getSimpleName(), msg); + } + + public static void i(Class clazz, String msg) { + if (isDebug) Log.i(clazz.getSimpleName(), msg); + } + + public static void w(Class clazz, String msg) { + if (isDebug) Log.w(clazz.getSimpleName(), msg); + } + + public static void e(Class clazz, String msg) { + if (isDebug) Log.e(clazz.getSimpleName(), msg); + } + +} \ No newline at end of file diff --git a/verification/src/main/java/com/dskj/verification/utils/NetUtil.java b/verification/src/main/java/com/dskj/verification/utils/NetUtil.java new file mode 100644 index 0000000..6b5cd55 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/utils/NetUtil.java @@ -0,0 +1,115 @@ +package com.dskj.verification.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.util.Log; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Map; + +public class NetUtil { + + private NetUtil() { + } + + public static boolean isNetworkConnected() { + if (AppContextUtil.getInstance() != null) { + ConnectivityManager mConnectivityManager = (ConnectivityManager) AppContextUtil.getInstance() + .getSystemService(Context.CONNECTIVITY_SERVICE); + @SuppressLint("MissingPermission") NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo(); + if (mNetworkInfo != null) { + return mNetworkInfo.isAvailable(); + } + } + return false; + } + + public static boolean isWifiConnected() { + if (AppContextUtil.getInstance() != null) { + ConnectivityManager mConnectivityManager = (ConnectivityManager) AppContextUtil.getInstance() + .getSystemService(Context.CONNECTIVITY_SERVICE); + @SuppressLint("MissingPermission") NetworkInfo mWiFiNetworkInfo = mConnectivityManager + .getNetworkInfo(ConnectivityManager.TYPE_WIFI); + if (mWiFiNetworkInfo != null) { + return mWiFiNetworkInfo.isAvailable(); + } + } + return false; + } + + public static boolean isMobileConnected() { + if (AppContextUtil.getInstance() != null) { + ConnectivityManager mConnectivityManager = (ConnectivityManager) AppContextUtil.getInstance() + .getSystemService(Context.CONNECTIVITY_SERVICE); + @SuppressLint("MissingPermission") NetworkInfo mMobileNetworkInfo = mConnectivityManager + .getNetworkInfo(ConnectivityManager.TYPE_MOBILE); + if (mMobileNetworkInfo != null) { + return mMobileNetworkInfo.isAvailable(); + } + } + return false; + } + + public static int getConnectedType() { + if (AppContextUtil.getInstance() != null) { + ConnectivityManager mConnectivityManager = (ConnectivityManager) AppContextUtil.getInstance() + .getSystemService(Context.CONNECTIVITY_SERVICE); + @SuppressLint("MissingPermission") NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo(); + if (mNetworkInfo != null && mNetworkInfo.isAvailable()) { + return mNetworkInfo.getType(); + } + } + return -1; + } + + public static String getRequestSign(Map map) { + String sb = ""; + String[] key = new String[map.size()]; + int index = 0; + for (String k : map.keySet()) { + key[index] = k; + index++; + } + Arrays.sort(key); + for (String s : key) { + sb += s + "-" + map.get(s) + "|"; + } + Log.e("-main-", sb.toString()); + System.out.println("接口参数:"+ sb); + Log.i("XHXDEBUG","XHXDEBUG走了前缀MD5"); + return md5("d43f467088e5e43ef7f80816c065705e" + sb); + } + + + public static String getRequestSign(String rand_str) { + String sb = "app_id=38923465&app_secret=EAXUfHJZKzWbwWPINQTXELYdhVBQRkVm&device_id="+rand_str; + LogUtils.i("签名数据0:"+sb); + return md5(sb); + } + + + public static String md5(String content) { + byte[] hash; + try { + hash = MessageDigest.getInstance("MD5").digest(content.getBytes("UTF-8")); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("NoSuchAlgorithmException", e); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("UnsupportedEncodingException", e); + } + + StringBuilder hex = new StringBuilder(hash.length * 2); + for (byte b : hash) { + if ((b & 0xFF) < 0x10) { + hex.append("0"); + } + hex.append(Integer.toHexString(b & 0xFF)); + } + return hex.toString(); + } +} diff --git a/verification/src/main/java/com/dskj/verification/utils/RxBus.java b/verification/src/main/java/com/dskj/verification/utils/RxBus.java new file mode 100644 index 0000000..47dcc8d --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/utils/RxBus.java @@ -0,0 +1,53 @@ +package com.dskj.verification.utils; + +import rx.Observable; +import rx.subjects.PublishSubject; +import rx.subjects.SerializedSubject; +import rx.subjects.Subject; + +public class RxBus { + + private static volatile RxBus instance; + + private final Subject bus; + + private RxBus() { + bus = new SerializedSubject<>(PublishSubject.create()); + } + + /** + * 单例模式RxBus + * + * @return + */ + public static RxBus getInstance() { + if (null == instance) { + synchronized (RxBus.class) { + if (null == instance) { + instance = new RxBus(); + } + } + } + return instance; + } + + /** + * 发送消息 + * + * @param o + */ + public void post(Object o) { + bus.onNext(o); + } + + /** + * 根据传递的 eventType 类型返回特定类型(eventType)的 被观察者 + * + * @param eventType + * @param + * @return + */ + public Observable toObservable(Class eventType) { + return bus.ofType(eventType); + } +} diff --git a/verification/src/main/java/com/dskj/verification/utils/ToastUtils.java b/verification/src/main/java/com/dskj/verification/utils/ToastUtils.java new file mode 100644 index 0000000..b169330 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/utils/ToastUtils.java @@ -0,0 +1,18 @@ +package com.dskj.verification.utils; + +import android.content.Context; +import android.view.Gravity; +import android.view.View; +import android.widget.Toast; + +import com.azhon.basic.utils.SnackbarUtils; +import com.google.android.material.snackbar.Snackbar; + +public class ToastUtils { + public static void showShort(View context, String name){ + Toast.makeText(context.getContext(),name,Toast.LENGTH_SHORT).show(); +// SnackbarUtils.Short(context,name).gravityFrameLayout(Gravity.TOP).show(); +// Snackbar.make(context, name, Snackbar.LENGTH_SHORT).show(); +// snackbar.show(); + } +} diff --git a/verification/src/main/java/com/dskj/verification/viewModel/home/MainViewModel.java b/verification/src/main/java/com/dskj/verification/viewModel/home/MainViewModel.java new file mode 100644 index 0000000..6538d55 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/viewModel/home/MainViewModel.java @@ -0,0 +1,103 @@ +package com.dskj.verification.viewModel.home; + +import android.util.Log; + +import androidx.lifecycle.MutableLiveData; + +import com.azhon.basic.lifecycle.BaseViewModel; +import com.dskj.verification.InitApp; +import com.dskj.verification.api.Api; +import com.dskj.verification.api.BaseObserver; +import com.dskj.verification.api.Result; +import com.dskj.verification.bean.ErrorMesage; +import com.dskj.verification.bean.TokenBean; +import com.dskj.verification.bean.UserBean; +import com.dskj.verification.bean.VideoIndexBean; +import com.dskj.verification.bean.VideoIndexResult; +import com.dskj.verification.bean.VideoResult; +import com.dskj.verification.utils.GetAndroidUniqueMark; +import com.dskj.verification.utils.LogUtils; +import com.dskj.verification.utils.NetUtil; + +import java.util.List; +import java.util.Random; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; + +public class MainViewModel extends BaseViewModel { + protected MutableLiveData tokenBeanMutableLiveData = new MutableLiveData<>(); + + public MutableLiveData getTokenBeanMutableLiveData() { + return tokenBeanMutableLiveData; + } + + protected MutableLiveData userBeanMutableLiveData = new MutableLiveData<>(); + + public MutableLiveData getUserBeanMutableLiveData() { + return userBeanMutableLiveData; + } + + private MutableLiveData errorMesageMutableLiveData = new MutableLiveData<>(); + + public MutableLiveData getErrorMesageMutableLiveData() { + return errorMesageMutableLiveData; + } + /** + * getAccessToken + * + * @param + */ + public void getAccessToken() { +// String device_id = GetAndroidUniqueMark.getUniqueId(InitApp.getAppContext()); + String app_id = "38923465"; + String rand_str =( new Random().nextInt(900000)+100000)+""; +// rand_str = "291187"; +// long timestamps = (System.currentTimeMillis()/1000); + String signature = NetUtil.getRequestSign(rand_str); + LogUtils.i("签名数据:"+signature); + Api.getInstance().getAccessToken(app_id, signature, rand_str) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>() { + + @Override + public void onSuccess(Result feedbackResp) { + getTokenBeanMutableLiveData().postValue(feedbackResp.data); + + } + @Override + public void onError(int code, String msg) { + getTokenBeanMutableLiveData().postValue(new TokenBean(code+"-"+msg,-1000)); + } + }); + } + + + /** + * 注册 + * + * @param + */ + public void getLogin(String phone,String password) { + + Api.getInstance().getLogin(phone, password) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver>() { + + @Override + public void onSuccess(Result feedbackResp) { +// getTokenBeanMutableLiveData().postValue(feedbackResp.data); + getUserBeanMutableLiveData().postValue(feedbackResp.data); + } + @Override + public void onError(int code, String msg) { + getErrorMesageMutableLiveData().postValue(new ErrorMesage(code,msg)); + } + }); + } + + + +} diff --git a/verification/src/main/java/com/dskj/verification/viewModel/home/SwitchVideoModel.java b/verification/src/main/java/com/dskj/verification/viewModel/home/SwitchVideoModel.java new file mode 100644 index 0000000..6974c13 --- /dev/null +++ b/verification/src/main/java/com/dskj/verification/viewModel/home/SwitchVideoModel.java @@ -0,0 +1,39 @@ +package com.dskj.verification.viewModel.home; + +import androidx.annotation.NonNull; + +/** + * Created by shuyu on 2016/12/7. + */ + +public class SwitchVideoModel { + private String url; + private String name; + + public SwitchVideoModel(String name, String url) { + this.name = name; + this.url = url; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @NonNull + @Override + public String toString() { + return this.name; + } +} diff --git a/verification/src/main/java/com/hitomi/tilibrary/transfer/ProgressBarIndicatorNew.java b/verification/src/main/java/com/hitomi/tilibrary/transfer/ProgressBarIndicatorNew.java new file mode 100644 index 0000000..3576752 --- /dev/null +++ b/verification/src/main/java/com/hitomi/tilibrary/transfer/ProgressBarIndicatorNew.java @@ -0,0 +1,69 @@ +package com.hitomi.tilibrary.transfer; + +import android.content.Context; +import android.util.SparseArray; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.ProgressBar; + +import com.hitomi.tilibrary.style.IProgressIndicator; + +/** + * 图片加载时使用 Android 默认的 ProgressBar + *

+ * email: 196425254@qq.com + */ +public class ProgressBarIndicatorNew implements IProgressIndicator { + +// private SparseArray progressBarArray = new SparseArray<>(); + +// private int dip2Px(Context context, float dpValue) { +//// final float scale = context.getResources().getDisplayMetrics().density; +//// return (int) (dpValue * scale + 0.5f); +// } + + @Override + public void attach(int position, FrameLayout parent) { +// Context context = parent.getContext(); +// +// int progressSize = dip2Px(context, 50); +// FrameLayout.LayoutParams progressLp = new FrameLayout.LayoutParams( +// progressSize, progressSize); +// progressLp.gravity = Gravity.CENTER; +// +// ProgressBar progressBar = new ProgressBar(context); +// progressBar.setLayoutParams(progressLp); +// +// parent.addView(progressBar, parent.getChildCount()); +// progressBarArray.put(position, progressBar); + } + + @Override + public void hideView(int position) { +// ProgressBar progressBar = progressBarArray.get(position); +// if (progressBar != null) +// progressBar.setVisibility(View.GONE); + } + + @Override + public void onStart(int position) { + } + + @Override + public void onProgress(int position, int progress) { + } + + @Override + public void onFinish(int position) { +// ProgressBar progressBar = progressBarArray.get(position); +// if (progressBar == null) return; +// +// ViewGroup vg = (ViewGroup) progressBar.getParent(); +// ; +// if (vg != null) { +// vg.removeView(progressBar); +// } + } +} diff --git a/verification/src/main/java/com/hitomi/tilibrary/transfer/TransfereeNew.java b/verification/src/main/java/com/hitomi/tilibrary/transfer/TransfereeNew.java new file mode 100644 index 0000000..432211e --- /dev/null +++ b/verification/src/main/java/com/hitomi/tilibrary/transfer/TransfereeNew.java @@ -0,0 +1,276 @@ +package com.hitomi.tilibrary.transfer; + +import android.app.Activity; +import android.app.Application; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.view.KeyEvent; +import android.widget.ImageView; + +import androidx.appcompat.app.AlertDialog; + +import com.gyf.immersionbar.ImmersionBar; +import com.hitomi.tilibrary.style.index.CircleIndexIndicator; +import com.hitomi.tilibrary.style.progress.ProgressBarIndicator; +import com.hitomi.tilibrary.utils.AppManager; +import com.hitomi.tilibrary.utils.FileUtils; +import com.hitomi.tilibrary.view.video.ExoVideoView; +import com.hitomi.tilibrary.view.video.source.ExoSourceManager; + +import java.io.File; + +/** + * Main workflow:
+ * 1、点击缩略图展示缩略图到 transferee 过渡动画
+ * 2、显示下载高清图片进度
+ * 3、加载完成显示高清图片
+ * 4、高清图支持手势缩放
+ * 5、关闭 transferee 展示 transferee 到原缩略图的过渡动画
+ * Created by Vans Z on 2017/1/19. + *

+ * email: 196425254@qq.com + */ +public class TransfereeNew implements DialogInterface.OnShowListener, + DialogInterface.OnKeyListener, + TransferLayout.OnLayoutResetListener, + AppManager.OnAppStateChangeListener { + + private Context context; + private Dialog transDialog; + + private TransferLayout transLayout; + private TransferConfig transConfig; + private OnTransfereeStateChangeListener transListener; + + // 因为Dialog的关闭有动画延迟,固不能使用 dialog.isShowing, 去判断 transferee 的显示逻辑 + private boolean shown; + + /** + * 构造方法私有化,通过{@link #getDefault(Context)} 创建 transferee + * + * @param context 上下文环境 + */ + private TransfereeNew(Context context) { + this.context = context; + createLayout(); + createDialog(); + AppManager.getInstance().init((Application) context.getApplicationContext()); + } + + /** + * @param context + * @return {@link TransfereeNew} + */ + public static TransfereeNew getDefault(Context context) { + return new TransfereeNew(context); + } + + private void createLayout() { + transLayout = new TransferLayout(context); + transLayout.setOnLayoutResetListener(this); + } + + private void createDialog() { + transDialog = new AlertDialog.Builder(context, + android.R.style.Theme_Translucent_NoTitleBar_Fullscreen) + .setView(transLayout) + .create(); + transDialog.setOnShowListener(this); + transDialog.setOnKeyListener(this); + } + + /** + * 检查参数,如果必须参数缺少,就使用缺省参数或者抛出异常 + */ + private void checkConfig() { + if (transConfig == null) + throw new IllegalArgumentException("The parameter TransferConfig can't be null"); + if (transConfig.isSourceEmpty()) + throw new IllegalArgumentException("The parameter sourceUrlList or sourceUriList can't be empty"); + if (transConfig.getImageLoader() == null) + throw new IllegalArgumentException("Need to specify an ImageLoader"); + + transConfig.setNowThumbnailIndex(Math.max(transConfig.getNowThumbnailIndex(), 0)); + transConfig.setOffscreenPageLimit(transConfig.getOffscreenPageLimit() <= 0 + ? 1 : transConfig.getOffscreenPageLimit()); + transConfig.setDuration(transConfig.getDuration() <= 0 + ? 300 : transConfig.getDuration()); + transConfig.setProgressIndicator(transConfig.getProgressIndicator() == null + ? new ProgressBarIndicator() : transConfig.getProgressIndicator()); + transConfig.setIndexIndicator(transConfig.getIndexIndicator() == null + ? new CircleIndexIndicator() : transConfig.getIndexIndicator()); + } + + /** + * 配置 transferee 参数对象 + * + * @param config 参数对象 + * @return transferee + */ + public TransfereeNew apply(TransferConfig config) { + if (!shown) { + transConfig = config; + OriginalViewHelper.getInstance().fillOriginImages(config); + checkConfig(); + transLayout.apply(config); + } + return this; + } + + /** + * transferee 是否显示 + * + * @return true :显示, false :关闭 + */ + public boolean isShown() { + return shown; + } + + /** + * 显示 transferee + */ + public void show() { + if (shown) return; + transDialog.show(); + adjustTopAndBottom(); + if (transListener != null) { + transListener.onShow(); + } + shown = true; + } + + /** + * 显示 transferee, 并设置 OnTransfereeChangeListener + * + * @param listener {@link OnTransfereeStateChangeListener} + */ + public void show(OnTransfereeStateChangeListener listener) { + if (shown || listener == null) return; + transDialog.show(); + adjustTopAndBottom(); + transListener = listener; + transListener.onShow(); + shown = true; + } + + /** + * 关闭 transferee + */ + public void dismiss() { + if (shown && transLayout.dismiss(transConfig.getNowThumbnailIndex())) { + shown = false; + } + } + + /** + * 获取图片文件 + */ + public File getImageFile(String imageUrl) { + return transConfig.getImageLoader().getCache(imageUrl); + } + + /** + * 清除 transferee 缓存,包括图片和视频文件缓存,注意清除视频缓存必须保证 transferee 是关闭状态 + */ + public void clear() { + if (transConfig != null && transConfig.getImageLoader() != null) { + transConfig.getImageLoader().clearCache(); + } + File cacheFile = new File(context.getCacheDir(), ExoVideoView.CACHE_DIR); + if (cacheFile.exists() && !shown) { + FileUtils.deleteDir(new File(cacheFile, VideoThumbState.FRAME_DIR)); + ExoSourceManager.clearCache(context, cacheFile, null); + } + } + + /** + * dialog 打开时的监听器 + */ + @Override + public void onShow(DialogInterface dialog) { + AppManager.getInstance().register(this); + transLayout.show(); + } + + /** + * 调整顶部和底部内边距 + */ + private void adjustTopAndBottom() { + if (context instanceof Activity) { + // 隐藏状态栏和导航栏,全屏化 + Activity activity = (Activity) context; + ImmersionBar.with(activity, transDialog) + .fullScreen(true) + .init(); +// int top = ImmersionBar.getNotchHeight(activity); +// int bottom = ImmersionBar.getNavigationBarHeight(activity); + transLayout.setPadding(0, 0, 0, 0); + } + } + + @Override + public void onReset() { + AppManager.getInstance().unregister(this); + transDialog.dismiss(); + if (transListener != null) + transListener.onDismiss(); + shown = false; + } + + @Override + public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK && + event.getAction() == KeyEvent.ACTION_UP && + !event.isCanceled()) { + dismiss(); + return true; + } + return false; + } + + @Override + public void onForeground() { + transLayout.pauseOrPlayVideo(false); + } + + @Override + public void onBackground() { + transLayout.pauseOrPlayVideo(true); + } + + /** + * 设置 Transferee 显示和关闭的监听器 + * + * @param listener {@link OnTransfereeStateChangeListener} + */ + public void setOnTransfereeStateChangeListener(OnTransfereeStateChangeListener listener) { + transListener = listener; + } + + /** + * 资源销毁,防止内存泄漏 + */ + public void destroy() { + if (transConfig != null) { + transConfig.destroy(); + transConfig = null; + } + } + + /** + * Transferee 显示的时候调用 {@link OnTransfereeStateChangeListener#onShow()} + *

+ * Transferee 关闭的时候调用 {@link OnTransfereeStateChangeListener#onDismiss()} + */ + public interface OnTransfereeStateChangeListener { + void onShow(); + + void onDismiss(); + } + + public interface OnTransfereeLongClickListener { + void onLongClick(ImageView imageView, String imageUri, int pos); + } + +} diff --git a/verification/src/main/res/anim/animate.xml b/verification/src/main/res/anim/animate.xml new file mode 100644 index 0000000..490eac7 --- /dev/null +++ b/verification/src/main/res/anim/animate.xml @@ -0,0 +1,7 @@ + + diff --git a/verification/src/main/res/anim/item_animation_fall_down.xml b/verification/src/main/res/anim/item_animation_fall_down.xml new file mode 100644 index 0000000..87c9ed7 --- /dev/null +++ b/verification/src/main/res/anim/item_animation_fall_down.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/verification/src/main/res/color/select_color.xml b/verification/src/main/res/color/select_color.xml new file mode 100644 index 0000000..044e023 --- /dev/null +++ b/verification/src/main/res/color/select_color.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/verification/src/main/res/color/select_color1.xml b/verification/src/main/res/color/select_color1.xml new file mode 100644 index 0000000..5d2a127 --- /dev/null +++ b/verification/src/main/res/color/select_color1.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/verification/src/main/res/drawable-v24/ic_launcher_foreground.xml b/verification/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/verification/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/verification/src/main/res/drawable/actionbar_bg.xml b/verification/src/main/res/drawable/actionbar_bg.xml new file mode 100644 index 0000000..a56c2dc --- /dev/null +++ b/verification/src/main/res/drawable/actionbar_bg.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/verification/src/main/res/drawable/bg_ripple.xml b/verification/src/main/res/drawable/bg_ripple.xml new file mode 100644 index 0000000..91536ad --- /dev/null +++ b/verification/src/main/res/drawable/bg_ripple.xml @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/verification/src/main/res/drawable/dialog_loading_bg1.xml b/verification/src/main/res/drawable/dialog_loading_bg1.xml new file mode 100644 index 0000000..2949026 --- /dev/null +++ b/verification/src/main/res/drawable/dialog_loading_bg1.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/verification/src/main/res/drawable/dlg_input_video_bg.xml b/verification/src/main/res/drawable/dlg_input_video_bg.xml new file mode 100644 index 0000000..1e5d9cf --- /dev/null +++ b/verification/src/main/res/drawable/dlg_input_video_bg.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/verification/src/main/res/drawable/ic_launcher_background.xml b/verification/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/verification/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/verification/src/main/res/drawable/inputbg.xml b/verification/src/main/res/drawable/inputbg.xml new file mode 100644 index 0000000..a1bb3d9 --- /dev/null +++ b/verification/src/main/res/drawable/inputbg.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/verification/src/main/res/drawable/inputbg_false.xml b/verification/src/main/res/drawable/inputbg_false.xml new file mode 100644 index 0000000..4ff38f6 --- /dev/null +++ b/verification/src/main/res/drawable/inputbg_false.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/verification/src/main/res/drawable/inputbg_true.xml b/verification/src/main/res/drawable/inputbg_true.xml new file mode 100644 index 0000000..1786790 --- /dev/null +++ b/verification/src/main/res/drawable/inputbg_true.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/verification/src/main/res/drawable/item_bg_default.xml b/verification/src/main/res/drawable/item_bg_default.xml new file mode 100644 index 0000000..af76fa0 --- /dev/null +++ b/verification/src/main/res/drawable/item_bg_default.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/verification/src/main/res/drawable/item_bg_default1.xml b/verification/src/main/res/drawable/item_bg_default1.xml new file mode 100644 index 0000000..10d93d6 --- /dev/null +++ b/verification/src/main/res/drawable/item_bg_default1.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/verification/src/main/res/drawable/item_bg_default2.xml b/verification/src/main/res/drawable/item_bg_default2.xml new file mode 100644 index 0000000..7e6b12e --- /dev/null +++ b/verification/src/main/res/drawable/item_bg_default2.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/verification/src/main/res/drawable/jz_bottom_seek_progress.xml b/verification/src/main/res/drawable/jz_bottom_seek_progress.xml new file mode 100644 index 0000000..8f4948e --- /dev/null +++ b/verification/src/main/res/drawable/jz_bottom_seek_progress.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/verification/src/main/res/drawable/jz_seek_post.xml b/verification/src/main/res/drawable/jz_seek_post.xml new file mode 100644 index 0000000..51affe0 --- /dev/null +++ b/verification/src/main/res/drawable/jz_seek_post.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/verification/src/main/res/drawable/save_btn_back.xml b/verification/src/main/res/drawable/save_btn_back.xml new file mode 100644 index 0000000..9d9f5e5 --- /dev/null +++ b/verification/src/main/res/drawable/save_btn_back.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/verification/src/main/res/drawable/search_bg.xml b/verification/src/main/res/drawable/search_bg.xml new file mode 100644 index 0000000..69d84da --- /dev/null +++ b/verification/src/main/res/drawable/search_bg.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/verification/src/main/res/drawable/tab_line.xml b/verification/src/main/res/drawable/tab_line.xml new file mode 100644 index 0000000..fdf31c3 --- /dev/null +++ b/verification/src/main/res/drawable/tab_line.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/verification/src/main/res/drawable/tab_line1.xml b/verification/src/main/res/drawable/tab_line1.xml new file mode 100644 index 0000000..6156b0c --- /dev/null +++ b/verification/src/main/res/drawable/tab_line1.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/verification/src/main/res/layout/activity_login.xml b/verification/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..92c915c --- /dev/null +++ b/verification/src/main/res/layout/activity_login.xml @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + +