init
This commit is contained in:
commit
a114220762
|
|
@ -0,0 +1,16 @@
|
|||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
Binary file not shown.
|
|
@ -0,0 +1,184 @@
|
|||
plugins {
|
||||
alias(libs.plugins.androidApplication)
|
||||
alias(libs.plugins.jetbrainsKotlinAndroid)
|
||||
id 'kotlin-kapt'
|
||||
id 'kotlin-parcelize'
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.cheng.bole'
|
||||
compileSdk 34
|
||||
buildFeatures.buildConfig = true
|
||||
|
||||
lintOptions{
|
||||
checkReleaseBuilds false
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.cheng.BoLe"
|
||||
minSdk 26
|
||||
targetSdk 34
|
||||
versionCode 240
|
||||
versionName "2.4.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables {
|
||||
useSupportLibrary true
|
||||
}
|
||||
ndk {
|
||||
abiFilters 'arm64-v8a' //'armeabi-v7a'
|
||||
}
|
||||
multiDexEnabled true
|
||||
|
||||
flavorDimensions = ["channel"]
|
||||
|
||||
productFlavors {
|
||||
xiaomi {}
|
||||
oppo {}
|
||||
vivo {}
|
||||
huawei {}
|
||||
honor {}
|
||||
baidu {}
|
||||
yyb {}
|
||||
upgrade {}
|
||||
bd_tg {}
|
||||
dy_tg {}
|
||||
tx_tg {}
|
||||
ks_tg {}
|
||||
dd_tg {}
|
||||
sm_tg {}
|
||||
oc_tg {}
|
||||
}
|
||||
|
||||
productFlavors.configureEach {
|
||||
dimension "channel"
|
||||
manifestPlaceholders = [UMENG_CHANNEL: name]
|
||||
}
|
||||
|
||||
manifestPlaceholders = [
|
||||
GETUI_APPID : "ej3hUPd0LR8G1CzkNtyZS3",
|
||||
GT_INSTALL_CHANNEL: "test",
|
||||
]
|
||||
}
|
||||
|
||||
// 配置签名信息
|
||||
signingConfigs {
|
||||
config {
|
||||
storeFile file(RELEASE_STORE_FILE)
|
||||
storePassword RELEASE_STORE_PASSWORD
|
||||
keyAlias RELEASE_KEY_ALIAS
|
||||
keyPassword RELEASE_KEY_PASSWORD
|
||||
enableV1Signing true
|
||||
enableV2Signing true
|
||||
enableV3Signing true
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
minifyEnabled false
|
||||
shrinkResources false
|
||||
signingConfig signingConfigs.config
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
release {
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
signingConfig signingConfigs.config
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
applicationVariants.configureEach { variant ->
|
||||
if (variant.buildType.name == "release") {
|
||||
variant.outputs.forEach {
|
||||
it.outputFileName = "material_v${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
|
||||
}
|
||||
|
||||
variant.assembleProvider.get().doLast {
|
||||
copy {
|
||||
variant.outputs.forEach { file ->
|
||||
//移动到指定文件夹
|
||||
ant.move file: file.outputFile,
|
||||
todir: "${project.rootDir}/apk"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variant.assembleProvider.get().doLast {
|
||||
android.buildTypes.each { buildType ->
|
||||
file("build/outputs/apk/$buildType").listFiles().each { channelFolder ->
|
||||
if (channelFolder.isDirectory() && channelFolder.getName() != outputApkFolder) {
|
||||
delete(channelFolder)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
|
||||
implementation project(':base')
|
||||
|
||||
implementation libs.androidx.appcompat
|
||||
implementation libs.com.google.android.material.material
|
||||
implementation libs.androidx.constraintlayout.constraintlayout
|
||||
testImplementation libs.junit
|
||||
androidTestImplementation libs.androidx.junit
|
||||
androidTestImplementation libs.androidx.espresso.core
|
||||
|
||||
// implementation "androidx.core:core-splashscreen:1.0.1"
|
||||
implementation 'com.jakewharton:disklrucache:2.0.2' // disklrucache
|
||||
|
||||
// tabLayout
|
||||
implementation 'com.github.angcyo.DslTablayout:TabLayout:3.7.2'
|
||||
implementation 'com.github.angcyo.DslTablayout:ViewPager1Delegate:3.7.2'
|
||||
|
||||
implementation 'com.github.FlyJingFish:GradientTextView:1.2.5' //渐变文字
|
||||
implementation 'com.github.aitsuki:SwipeMenuRecyclerView:2.1.5' // 侧滑菜单
|
||||
implementation 'com.github.chrisbanes:PhotoView:2.3.0' //图片浏览
|
||||
implementation 'io.github.billywei01:fastaes:1.1.3' //解密
|
||||
implementation 'com.github.gzu-liyujiang:Android_CN_OAID:4.2.12' //获取手机设备id
|
||||
implementation 'com.google.android.flexbox:flexbox:3.0.0' //recyclerview flexbox
|
||||
|
||||
implementation files('libs/channelsdk-0.2.2.aar') //快手分包
|
||||
implementation 'com.tencent.vasdolly:helper:3.0.4' //腾讯分包
|
||||
implementation files('libs/humesdk-1.0.0.aar') //巨量分包
|
||||
|
||||
implementation 'com.getui:gysdk:3.1.7.0' //一键认证sdk
|
||||
implementation 'com.getui:gtc:3.2.16.0' //个推公共库,如已接其他个推sdk则保留一个最高版本即可
|
||||
|
||||
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:6.8.0' //微信
|
||||
//友盟
|
||||
implementation 'com.umeng.umsdk:common:9.6.3'// 必选
|
||||
implementation 'com.umeng.umsdk:asms:1.8.0'// 必选
|
||||
implementation 'com.umeng.umsdk:apm:1.9.1' // U-APM包依赖(必选)
|
||||
implementation 'com.umeng.umsdk:share-core:7.3.2'//分享核心库,必选
|
||||
implementation 'com.umeng.umsdk:share-wx:7.3.2' //微信完整版
|
||||
|
||||
implementation 'top.zibin:Luban:1.1.8' //图片压缩
|
||||
implementation 'com.github.Dimezis:BlurView:version-2.0.6' //毛玻璃效果
|
||||
implementation 'com.bytedance.ads:AppConvert:2.0.0' //巨量融合
|
||||
implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:4.1.14' // 滚轮选择器
|
||||
//media3视频播放
|
||||
implementation "androidx.media3:media3-exoplayer:1.4.1"
|
||||
implementation "androidx.media3:media3-ui:1.4.1"
|
||||
implementation "androidx.media3:media3-common:1.4.1"
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,358 @@
|
|||
# 代码混淆压缩比,在0~7之间,默认为5,一般不做修改
|
||||
-optimizationpasses 5
|
||||
# 混合时不使用大小写混合,混合后的类名为小写
|
||||
-dontusemixedcaseclassnames
|
||||
# 指定不去忽略非公共库的类
|
||||
-dontskipnonpubliclibraryclasses
|
||||
# 这句话能够使我们的项目混淆后产生映射文件
|
||||
# 包含有类名->混淆后类名的映射关系
|
||||
-verbose
|
||||
# 指定不去忽略非公共库的类成员
|
||||
-dontskipnonpubliclibraryclassmembers
|
||||
# 不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。
|
||||
-dontpreverify
|
||||
# 保留Annotation不混淆
|
||||
-keepattributes *Annotation*,InnerClasses
|
||||
# 避免混淆泛型
|
||||
-keepattributes Signature
|
||||
# 抛出异常时保留代码行号
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
# 指定混淆是采用的算法,后面的参数是一个过滤器
|
||||
# 这个过滤器是谷歌推荐的算法,一般不做更改
|
||||
-optimizations !code/simplification/cast,!field/*,!class/merging/*
|
||||
|
||||
#############################################
|
||||
#
|
||||
# Android开发中一些需要保留的公共部分
|
||||
#
|
||||
#############################################
|
||||
|
||||
# 保留我们使用的四大组件,自定义的Application等等这些类不被混淆
|
||||
# 因为这些子类都有可能被外部调用
|
||||
-keep public class * extends android.app.Activity
|
||||
-keep public class * extends android.app.Appliction
|
||||
-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 public class * extends android.view.View
|
||||
-keep public class com.android.vending.licensing.ILicensingService
|
||||
|
||||
# 保留support下的所有类及其内部类
|
||||
-keep class android.support.** {*;}
|
||||
#kotlin
|
||||
-keep class kotlin.** { *; }
|
||||
-keep class kotlin.Metadata { *; }
|
||||
-dontwarn kotlin.**
|
||||
-keepclassmembers class **$WhenMappings {
|
||||
<fields>;
|
||||
}
|
||||
-keepclassmembers class kotlin.Metadata {
|
||||
public <methods>;
|
||||
}
|
||||
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
|
||||
static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
|
||||
}
|
||||
|
||||
# 保留继承的
|
||||
-keep public class * extends android.support.v4.**
|
||||
-keep public class * extends android.support.v7.**
|
||||
-keep public class * extends android.support.annotation.**
|
||||
|
||||
-keep class com.google.android.material.** {*;}
|
||||
-keep class androidx.** {*;}
|
||||
-keep public class * extends androidx.**
|
||||
-keep interface androidx.** {*;}
|
||||
-dontwarn com.google.android.material.**
|
||||
-dontnote com.google.android.material.**
|
||||
-dontwarn androidx.**
|
||||
|
||||
|
||||
# 保留R下面的资源
|
||||
-keep class **.R$* {*;}
|
||||
|
||||
# 保留本地native方法不被混淆
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
# 保留binding方法不被混淆
|
||||
-keepclassmembers class ** implements androidx.viewbinding.ViewBinding {
|
||||
public static ** bind(***);
|
||||
public static ** inflate(***);
|
||||
}
|
||||
|
||||
# 保留在Activity中的方法参数是view的方法,
|
||||
# 这样以来我们在layout中写的onClick就不会被影响
|
||||
-keepclassmembers class * extends android.app.Activity{
|
||||
public void *(android.view.View);
|
||||
}
|
||||
|
||||
# 保留我们自定义控件(继承自View)不被混淆
|
||||
-keep public class * extends android.view.View{
|
||||
*** get*();
|
||||
void set*(***);
|
||||
public <init>(android.content.Context);
|
||||
public <init>(android.content.Context, android.util.AttributeSet);
|
||||
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||
}
|
||||
|
||||
# 保留Parcelable序列化类不被混淆
|
||||
-keep class * implements android.os.Parcelable {
|
||||
public static final android.os.Parcelable$Creator *;
|
||||
}
|
||||
|
||||
# 保留Serializable序列化的类不被混淆
|
||||
-keepclassmembers class * implements java.io.Serializable {
|
||||
static final long serialVersionUID;
|
||||
private static final java.io.ObjectStreamField[] serialPersistentFields;
|
||||
!static !transient <fields>;
|
||||
!private <fields>;
|
||||
!private <methods>;
|
||||
private void writeObject(java.io.ObjectOutputStream);
|
||||
private void readObject(java.io.ObjectInputStream);
|
||||
java.lang.Object writeReplace();
|
||||
java.lang.Object readResolve();
|
||||
}
|
||||
|
||||
-keep public class * implements java.io.Serializable {*;}
|
||||
|
||||
# 不混淆实体类
|
||||
-keep class com.cheng.bole.bean.** { *; }
|
||||
-keep class com.cheng.bole.bean.db.** { *; }
|
||||
-keep class com.cheng.bole.net.model.** { *; }
|
||||
|
||||
# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
|
||||
-keepclassmembers class * {
|
||||
void *(**On*Event);
|
||||
void *(**On*Listener);
|
||||
}
|
||||
|
||||
# 移除Log类打印各个等级日志的代码,打正式包的时候可以做为禁log使用,这里可以作为禁止log打印的功能使用
|
||||
# 记得proguard-android.txt中一定不要加-dontoptimize才起作用
|
||||
# 另外的一种实现方案是通过BuildConfig.DEBUG的变量来控制
|
||||
-assumenosideeffects class android.util.Log {
|
||||
public static int v(...);
|
||||
public static int i(...);
|
||||
public static int w(...);
|
||||
public static int d(...);
|
||||
public static int e(...);
|
||||
}
|
||||
|
||||
# fastJson
|
||||
-dontwarn com.alibaba.fastjson.**
|
||||
-keep class com.alibaba.fastjson.** { *; }
|
||||
-keepattributes *Annotation*
|
||||
|
||||
# gson
|
||||
-keep class com.google.gson.reflect.TypeToken { *; }
|
||||
-keep class * extends com.google.gson.reflect.TypeToken
|
||||
-keepattributes AnnotationDefault,RuntimeVisibleAnnotations
|
||||
|
||||
# 保留Gson核心类和方法,防止它们被混淆
|
||||
-dontwarn sun.misc.**
|
||||
-keep class com.google.gson.** { *; }
|
||||
-keep class com.google.gson.examples.android.model.** { <fields>; }
|
||||
-keep class * implements com.google.gson.TypeAdapterFactory
|
||||
-keep class * implements com.google.gson.JsonSerializer
|
||||
-keep class * implements com.google.gson.JsonDeserializer
|
||||
|
||||
|
||||
# 保持Gson序列化和反序列化所需的注解不被混淆
|
||||
-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault
|
||||
|
||||
-keepclassmembernames class * {
|
||||
@com.google.gson.annotations.SerializedName <fields>;
|
||||
}
|
||||
|
||||
# 保持枚举类型的序列化兼容性
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
# 防止R8或ProGuard移除未使用的元素(如果这些元素是通过反射访问的,比如Gson)
|
||||
-keep class * {
|
||||
@com.google.gson.annotations.SerializedName *;
|
||||
}
|
||||
-keepclassmembers class com.example.base.extensions.GsonExtensionsKt {
|
||||
<methods>;
|
||||
}
|
||||
|
||||
-keepclassmembers,allowobfuscation class * {
|
||||
@com.google.gson.annotations.SerializedName <fields>;
|
||||
}
|
||||
|
||||
# Glide
|
||||
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
|
||||
**[] $VALUES;
|
||||
public *;
|
||||
}
|
||||
|
||||
# OkHttp3
|
||||
-dontwarn com.squareup.okhttp3.**
|
||||
-keep class com.squareup.okhttp3.** { *;}
|
||||
-dontwarn okio.**
|
||||
|
||||
# Okio
|
||||
-dontwarn com.squareup.**
|
||||
-dontwarn okio.**
|
||||
-keep public class org.codehaus.* { *; }
|
||||
-keep public class java.nio.* { *; }
|
||||
|
||||
# Retrofit
|
||||
-dontwarn retrofit2.**
|
||||
-keep class retrofit2.** { *; }
|
||||
-keepattributes Signature
|
||||
-keepattributes Exceptions
|
||||
|
||||
# liveDataBus
|
||||
-dontwarn com.jeremyliao.liveeventbus.**
|
||||
-keep class com.jeremyliao.liveeventbus.** { *; }
|
||||
-keep class androidx.lifecycle.** { *; }
|
||||
-keep class androidx.arch.core.** { *; }
|
||||
|
||||
# 微信
|
||||
-keep class com.tencent.mm.opensdk.** { *; }
|
||||
-keep class com.tencent.wxop.** { *; }
|
||||
-keep class com.tencent.mm.sdk.** { *; }
|
||||
|
||||
# 支付宝
|
||||
-libraryjars libs/alipaysdk-15.8.03.210428205839.aar
|
||||
-keep class com.alipay.android.app.IAlixPay{*;}
|
||||
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
|
||||
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
|
||||
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
|
||||
-keep class com.alipay.sdk.app.PayTask{ public *;}
|
||||
-keep class com.alipay.sdk.app.AuthTask{ public *;}
|
||||
|
||||
# 友盟
|
||||
-keep class com.umeng.** {*;}
|
||||
-keep class org.repackage.** {*;}
|
||||
|
||||
-keepclassmembers class * {
|
||||
public <init> (org.json.JSONObject);
|
||||
}
|
||||
|
||||
-keep public class com.chat.assistant.ai.R$*{
|
||||
public static final int *;
|
||||
}
|
||||
|
||||
#加载动画
|
||||
-keep class com.wang.avi.** { *; }
|
||||
-keep class com.wang.avi.indicators.** { *; }
|
||||
|
||||
#oss
|
||||
-keep class com.alibaba.sdk.android.oss.** { *; }
|
||||
-dontwarn okio.**
|
||||
-dontwarn org.apache.commons.codec.binary.**
|
||||
-keep class com.alibaba.idst.nui.*{*;}
|
||||
|
||||
##高德
|
||||
#定位
|
||||
-keep class com.amap.api.location.**{*;}
|
||||
-keep class com.amap.api.fence.**{*;}
|
||||
-keep class com.loc.**{*;}
|
||||
-keep class com.autonavi.aps.amapapi.model.**{*;}
|
||||
#地图
|
||||
-keep class com.amap.api.maps.**{*;}
|
||||
-keep class com.autonavi.**{*;}
|
||||
-keep class com.amap.api.trace.**{*;}
|
||||
#2D地图
|
||||
-keep class com.amap.api.maps2d.**{*;}
|
||||
-keep class com.amap.api.mapcore2d.**{*;}
|
||||
#搜索
|
||||
-keep class com.amap.api.services.**{*;}
|
||||
|
||||
#room
|
||||
-keep class androidx.room.** { *; }
|
||||
-keepclassmembers class * {
|
||||
@androidx.room.* <methods>;
|
||||
@androidx.room.* <fields>;
|
||||
}
|
||||
|
||||
-keep interface com.cheng.bole.manager.db.* { *; }
|
||||
-keepclassmembers class * extends androidx.room.RoomDatabase {
|
||||
public <init>(...);
|
||||
}
|
||||
|
||||
-keep class com.hjq.permissions.** {*;}
|
||||
|
||||
-keep class org.libpag.** {*;}
|
||||
-keep class androidx.exifinterface.** {*;}
|
||||
|
||||
-dontwarn io.microshow.rxffmpeg.**
|
||||
-keep class io.microshow.rxffmpeg.**{*;}
|
||||
|
||||
# 华为推送
|
||||
-ignorewarnings
|
||||
-keepattributes *Annotation*
|
||||
-keepattributes Exceptions
|
||||
-keepattributes InnerClasses
|
||||
-keepattributes Signature
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
-keep class com.huawei.hianalytics.**{*;}
|
||||
-keep class com.huawei.updatesdk.**{*;}
|
||||
-keep class com.huawei.hms.**{*;}
|
||||
|
||||
#腾讯语音识别
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
-keep public class com.tencent.cloud.qcloudasrsdk.*
|
||||
|
||||
-dontwarn com.bun.miitmdid.interfaces.IIdentifierListener
|
||||
-dontwarn com.download.library.DownloadTask$DownloadTaskStatus
|
||||
-dontwarn com.google.j2objc.annotations.Weak
|
||||
-dontwarn com.oracle.svm.core.annotate.Delete
|
||||
-dontwarn com.oracle.svm.core.annotate.TargetClass
|
||||
-dontwarn com.sun.tools.javac.code.Attribute$UnresolvedClass
|
||||
-dontwarn com.sun.tools.javac.code.Type$ClassType
|
||||
-dontwarn javax.lang.model.SourceVersion
|
||||
-dontwarn javax.lang.model.element.AnnotationMirror
|
||||
-dontwarn javax.lang.model.element.AnnotationValue
|
||||
-dontwarn javax.lang.model.element.AnnotationValueVisitor
|
||||
-dontwarn javax.lang.model.element.Element
|
||||
-dontwarn javax.lang.model.element.ElementKind
|
||||
-dontwarn javax.lang.model.element.ExecutableElement
|
||||
-dontwarn javax.lang.model.element.Modifier
|
||||
-dontwarn javax.lang.model.element.Name
|
||||
-dontwarn javax.lang.model.element.NestingKind
|
||||
-dontwarn javax.lang.model.element.PackageElement
|
||||
-dontwarn javax.lang.model.element.TypeElement
|
||||
-dontwarn javax.lang.model.element.TypeParameterElement
|
||||
-dontwarn javax.lang.model.element.VariableElement
|
||||
-dontwarn javax.lang.model.type.DeclaredType
|
||||
-dontwarn javax.lang.model.type.TypeKind
|
||||
-dontwarn javax.lang.model.type.TypeMirror
|
||||
-dontwarn javax.lang.model.type.TypeVariable
|
||||
-dontwarn javax.lang.model.type.TypeVisitor
|
||||
-dontwarn javax.lang.model.util.Elements
|
||||
-dontwarn javax.lang.model.util.SimpleAnnotationValueVisitor7
|
||||
-dontwarn javax.lang.model.util.SimpleTypeVisitor7
|
||||
-dontwarn javax.lang.model.util.Types
|
||||
-dontwarn org.bouncycastle.asn1.gm.GMNamedCurves
|
||||
-dontwarn org.bouncycastle.asn1.x9.X9ECParameters
|
||||
-dontwarn org.bouncycastle.crypto.digests.SM3Digest
|
||||
-dontwarn org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey
|
||||
-dontwarn org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
-dontwarn org.bouncycastle.jce.spec.ECParameterSpec
|
||||
-dontwarn org.bouncycastle.jce.spec.ECPublicKeySpec
|
||||
-dontwarn org.bouncycastle.jsse.BCSSLParameters
|
||||
-dontwarn org.bouncycastle.jsse.BCSSLSocket
|
||||
-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
|
||||
-dontwarn org.bouncycastle.math.ec.ECCurve
|
||||
-dontwarn org.bouncycastle.math.ec.ECPoint
|
||||
-dontwarn org.bouncycastle.util.encoders.Hex
|
||||
-dontwarn org.conscrypt.Conscrypt$Version
|
||||
-dontwarn org.conscrypt.Conscrypt
|
||||
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
|
||||
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
|
||||
-dontwarn org.openjsse.net.ssl.OpenJSSE
|
||||
-dontwarn com.efs.sdk.base.core.config.GlobalInfo
|
||||
-dontwarn com.efs.sdk.base.core.config.GlobalInfoManager
|
||||
-dontwarn coil.compose.EqualityDelegate
|
||||
-dontwarn coil.compose.SingletonAsyncImageKt
|
||||
-dontwarn android.os.SystemProperties
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.cheng.bole
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.cheng.bole", appContext.packageName)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-feature android:name="android.hardware.camera.any" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
||||
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
<uses-permission
|
||||
android:name="android.permission.INSTALL_PACKAGES"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
|
||||
<!--通知相关-->
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
|
||||
<queries>
|
||||
<package android:name="com.eg.android.AlipayGphone" /> <!-- 支付宝 -->
|
||||
<package android:name="hk.alipay.wallet" /> <!-- AlipayHK -->
|
||||
</queries>
|
||||
|
||||
<queries>
|
||||
<package android:name="com.tencent.mm" />
|
||||
</queries>
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="com.getui.sdk.action" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<queries package="${applicationId}">
|
||||
<intent>
|
||||
<action android:name="android.media.action.IMAGE_CAPTURE" />
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.media.action.ACTION_VIDEO_CAPTURE" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<application
|
||||
android:name=".BaseApplication"
|
||||
android:allowBackup="true"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
android:hardwareAccelerated="true"
|
||||
android:icon="@mipmap/ic_launcher_icon"
|
||||
android:label="@string/app_name"
|
||||
android:maxAspectRatio="2.4"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:resizeableActivity="true"
|
||||
android:roundIcon="@mipmap/ic_launcher_icon"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Material"
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:replace="android:allowBackup,android:supportsRtl">
|
||||
|
||||
<meta-data
|
||||
android:name="UMENG_CHANNEL"
|
||||
android:value="${UMENG_CHANNEL}" />
|
||||
|
||||
<meta-data
|
||||
android:name="UMENG_APPKEY"
|
||||
android:value="" />
|
||||
|
||||
<uses-library
|
||||
android:name="org.apache.http.legacy"
|
||||
android:required="false" />
|
||||
|
||||
<meta-data
|
||||
android:name="ScopedStorage"
|
||||
android:value="true" />
|
||||
|
||||
<meta-data
|
||||
android:name="android.max_aspect"
|
||||
android:value="2.4" />
|
||||
<!--适配华为(huawei)刘海屏-->
|
||||
<meta-data
|
||||
android:name="android.notch_support"
|
||||
android:value="true" />
|
||||
<!--适配小米(xiaomi)刘海屏-->
|
||||
<meta-data
|
||||
android:name="notch.config"
|
||||
android:value="portrait|landscape" />
|
||||
|
||||
<activity
|
||||
android:name="com.cheng.bole.ui.activity.LauncherActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/SplashTheme">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.cheng.bole.ui.activity.LoginActivity"
|
||||
android:configChanges="keyboardHidden|smallestScreenSize|orientation|screenSize"
|
||||
android:exported="true"
|
||||
android:label="登录"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.cheng.bole.ui.activity.MainActivity"
|
||||
android:configChanges="keyboardHidden|smallestScreenSize|orientation|screenSize"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="portrait">
|
||||
<intent-filter tools:ignore="AppLinkUrlError">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<!-- 指定分享类型-->
|
||||
<data android:mimeType="text/plain" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.cheng.bole.ui.activity.GuideActivity"
|
||||
android:configChanges="keyboardHidden|smallestScreenSize|orientation|screenSize"
|
||||
android:exported="true"
|
||||
android:label="引导页"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.cheng.bole.ui.activity.PublicActivity"
|
||||
android:configChanges="keyboardHidden|smallestScreenSize|orientation|screenSize"
|
||||
android:label="通用的Activity"
|
||||
android:launchMode="standard"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustPan|stateHidden" />
|
||||
|
||||
<activity
|
||||
android:name="com.cheng.bole.ui.activity.DrawerActivity"
|
||||
android:configChanges="keyboardHidden|smallestScreenSize|orientation|screenSize"
|
||||
android:label="通用的Activity"
|
||||
android:launchMode="standard"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/TransparentTheme"
|
||||
android:windowSoftInputMode="stateHidden" />
|
||||
|
||||
<activity
|
||||
android:name="com.cheng.bole.ui.activity.VideoPlayerActivity"
|
||||
android:configChanges="keyboardHidden|smallestScreenSize|orientation|screenSize"
|
||||
android:label="视频播放器"
|
||||
android:launchMode="standard"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.cheng.bole.wxapi.WXEntryActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:exported="true"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
|
||||
|
||||
<activity
|
||||
android:name="com.cheng.bole.wxapi.WXPayEntryActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/filepath_data" />
|
||||
</provider>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,90 @@
|
|||
package com.cheng.bole
|
||||
|
||||
import com.cheng.bole.utils.ChannelUtils
|
||||
import com.cheng.bole.common.Constants
|
||||
import com.example.base.MvvmApplication
|
||||
import com.example.base.utils.L
|
||||
import com.example.base.utils.MMKVUtils
|
||||
import com.example.base.utils.Utils
|
||||
import com.g.gysdk.GYManager
|
||||
import com.g.gysdk.GYResponse
|
||||
import com.g.gysdk.GyCallBack
|
||||
import com.g.gysdk.GyConfig
|
||||
import com.scwang.smart.refresh.header.MaterialHeader
|
||||
import com.scwang.smart.refresh.layout.SmartRefreshLayout
|
||||
import com.tencent.mmkv.MMKV
|
||||
import com.umeng.analytics.MobclickAgent
|
||||
import com.umeng.commonsdk.UMConfigure
|
||||
import com.umeng.socialize.PlatformConfig
|
||||
|
||||
|
||||
class BaseApplication : MvvmApplication() {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
Utils.init(this)
|
||||
MMKV.initialize(this)
|
||||
preInitUM()
|
||||
preInitGT()
|
||||
initRefreshLayout()
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化友盟
|
||||
*/
|
||||
private fun preInitUM() {
|
||||
UMConfigure.setLogEnabled(true)
|
||||
|
||||
PlatformConfig.setFileProvider(Constants.AppFilter)
|
||||
PlatformConfig.setWeixin(Constants.WechatAppId, Constants.WechatAppSecret)
|
||||
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO)
|
||||
|
||||
UMConfigure.setProcessEvent(true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 个推初始化
|
||||
*/
|
||||
private fun preInitGT() {
|
||||
if (MMKVUtils.getBoolean("isAgree")) {
|
||||
try {
|
||||
GYManager.getInstance().preInit(this) //个验SDK初始化
|
||||
GYManager.getInstance().init(
|
||||
GyConfig.with(this)
|
||||
.preLoginUseCache(true)//预取号使用缓存,可以提高预取号的成功率,建议设置为true
|
||||
.channel(ChannelUtils.getChannel())//应用渠道
|
||||
.eLoginDebug(BuildConfig.DEBUG)//运营商debug调试模式
|
||||
.debug(BuildConfig.DEBUG)//个验debug调试模式
|
||||
.callBack(object : GyCallBack {
|
||||
override fun onSuccess(gyResponse: GYResponse) {
|
||||
L.d("TAG-->>GYManager init onSuccess =${gyResponse.code}")
|
||||
}
|
||||
|
||||
override fun onFailed(gyResponse: GYResponse) {
|
||||
L.d("TAG-->>GYManager init onFailed =${gyResponse.code}")
|
||||
}
|
||||
}).build()
|
||||
)
|
||||
//预登录
|
||||
GYManager.getInstance().ePreLogin(8000, object : GyCallBack {
|
||||
override fun onSuccess(gyResponse: GYResponse) {
|
||||
L.d("TAG-->>GYManager ePreLogin onSuccess =${gyResponse.code}")
|
||||
}
|
||||
|
||||
override fun onFailed(gyResponse: GYResponse) {
|
||||
L.d("TAG-->>GYManager ePreLogin onFailed =${gyResponse.code}")
|
||||
}
|
||||
})
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initRefreshLayout() {
|
||||
//设置全局的Header构建器
|
||||
SmartRefreshLayout.setDefaultRefreshHeaderCreator { context, _ ->
|
||||
MaterialHeader(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
data class AccountEntity(
|
||||
val avater: String,
|
||||
val bind: List<String>,
|
||||
val create_time: String,
|
||||
val name: String,
|
||||
val phone: String,
|
||||
val role: Int,
|
||||
val temp: Boolean,
|
||||
val user_id: String,
|
||||
val vip_name: String,
|
||||
val vip_type: String
|
||||
) : Serializable
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
data class AdIncentiveEntity(
|
||||
val ad_code: String,
|
||||
val ad_count: Int,
|
||||
val ad_height: Int,
|
||||
val ad_width: Int,
|
||||
val is_visible: Boolean,
|
||||
val reward_count: Int,
|
||||
val reward_name: String
|
||||
) : Serializable
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
data class BannerEntity(
|
||||
val image: String,
|
||||
val page: String,
|
||||
val type: String
|
||||
) : Serializable
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
class ConfigEntity {
|
||||
|
||||
@SerializedName("client.version.upgrade")
|
||||
var versionEntity: com.cheng.bole.bean.VersionEntity? = null
|
||||
|
||||
@SerializedName("client.weixin.share") //微信分享
|
||||
var wxShareEntity: com.cheng.bole.bean.WxShareEntity? = null
|
||||
|
||||
@SerializedName("client.guide.pay.enable")
|
||||
var guidePayEnable: Boolean? = true //引导页是否开启支付,默认可以
|
||||
|
||||
@SerializedName("client.guide.enable")
|
||||
var guideEnable: Boolean? = true //是否开启引导页
|
||||
|
||||
@SerializedName("client.start.function.hint")
|
||||
var guideHint: String? = ""
|
||||
|
||||
@SerializedName("client.nologin.pay.enable")
|
||||
var noLoginPayEnable: Boolean? = false
|
||||
|
||||
@SerializedName("client.pay.agreement") //是否显示支付协议
|
||||
var payAgreementEnable: Boolean? = true
|
||||
|
||||
@SerializedName("client.login.type") //登录方式
|
||||
var loginType: List<String>? = emptyList()
|
||||
|
||||
@SerializedName("client.banner.urls") //首页banner
|
||||
var banners: List<com.cheng.bole.bean.BannerEntity>? = emptyList()
|
||||
|
||||
@SerializedName("client.ad.switch") //广告总开关
|
||||
var adSwitch: Boolean = false
|
||||
|
||||
@SerializedName("client.service.phone") //客服电话
|
||||
var servicePhoneList: List<String> = emptyList()
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.ylqh.cube.bean
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
data class CouponActivityEntity(
|
||||
val id: String = "",
|
||||
val activity_desc: String = "",
|
||||
val activity_name: String = "",
|
||||
val activity_threshold: String = "",
|
||||
val activity_type: String = "",
|
||||
val activity_type_name: String = "",
|
||||
val activity_value: String = "",
|
||||
var enableAnim: Boolean = true
|
||||
): Serializable
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
data class CouponEntity(
|
||||
val id: String,
|
||||
val status: String,
|
||||
val status_name: String,
|
||||
val threshold: String,
|
||||
val coupon_desc: String,
|
||||
val coupon_name: String,
|
||||
val coupon_type: String,
|
||||
val coupon_type_name: String,
|
||||
val coupon_value: String,
|
||||
val coupon_value_name: String,
|
||||
val create_time: String,
|
||||
val expire_time: String,
|
||||
val expire_timestamp: String,
|
||||
var isChecked: Boolean = false
|
||||
) : Serializable {
|
||||
companion object {
|
||||
const val TYPE_CASH = "1"
|
||||
const val TYPE_DISCOUNT = "2"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
class LoginEntity {
|
||||
val user_id: String = ""
|
||||
val name: String = ""
|
||||
val avater: String = ""
|
||||
val token: String = ""
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
data class NoticeEntity(
|
||||
val loop: Boolean,
|
||||
val notice: List<String>?
|
||||
) {
|
||||
data class NoticeItem(
|
||||
val message: String,
|
||||
var loop: Boolean = false
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
class OrderPayEntity {
|
||||
var appId = ""
|
||||
var orderId = ""
|
||||
var outTradeNo = ""
|
||||
var payParam = ""
|
||||
var payType = ""
|
||||
|
||||
var nonceStr = ""
|
||||
var `package` = ""
|
||||
var partnerId = ""
|
||||
var prepayId = ""
|
||||
var sign = ""
|
||||
var timeStamp = ""
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
data class PushPayloadEntity(
|
||||
val msgId: String,
|
||||
val page: String,
|
||||
val params: String
|
||||
): Serializable
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
class SendCodeEntity {
|
||||
val timestamp: String = ""
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
class UploadImgEntity : Serializable {
|
||||
var id = ""
|
||||
var url = ""
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
class UserConfigEntity : Serializable{
|
||||
var token = ""
|
||||
var temp = false
|
||||
var name = ""
|
||||
var user_id = ""
|
||||
var config: com.cheng.bole.bean.ConfigEntity? = null
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
data class UserEntity(
|
||||
val appleid: String,
|
||||
val avater: String,
|
||||
val balance: String,
|
||||
val city: String,
|
||||
val client_cid: String,
|
||||
val country: String,
|
||||
val coupon_count: Int,
|
||||
val imei: String,
|
||||
val month_download_count: String,
|
||||
val month_download_size: String,
|
||||
val name: String,
|
||||
val oaid: String,
|
||||
val os_version: String,
|
||||
val phone: String,
|
||||
val province: String,
|
||||
val role: String,
|
||||
val sex: Int,
|
||||
val show_contact_menu: Boolean,
|
||||
val show_masonry_menu: Boolean,
|
||||
val temp: Boolean,
|
||||
val unionid: String,
|
||||
val user_id: String,
|
||||
val vip: String, // 1非会员 2会员 3终生会员
|
||||
val vip_expire: String,
|
||||
val vip_expire_time: String,
|
||||
val vip_name: String,
|
||||
val weixinAppOpenId: String,
|
||||
val ip_area: String
|
||||
) : Serializable
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
class VersionEntity : Serializable {
|
||||
|
||||
var description = ""
|
||||
var force = false
|
||||
var last_version_force = ""
|
||||
var title = ""
|
||||
var url = ""
|
||||
var app_size = ""
|
||||
var version = ""
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
class VipGoodsEntity {
|
||||
var checked: Boolean = false
|
||||
var goods_id: String = ""
|
||||
var goods_name: String = ""
|
||||
var origin_price: String = ""
|
||||
var pay_type: String = ""
|
||||
var price: String = ""
|
||||
var single_pay_price: String = ""
|
||||
var tips: String = ""
|
||||
var sign_value = ""
|
||||
var value: String = ""
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
data class VipPermissionEntity(
|
||||
val auth: Boolean,
|
||||
val auth_ad: Boolean,
|
||||
val scene: String,
|
||||
val user_id: Int,
|
||||
val vip: Int,
|
||||
val vip_expire: String,
|
||||
val vip_expire_time: String,
|
||||
val vip_goods_type: String,
|
||||
val vip_message: String,
|
||||
val vip_name: String,
|
||||
var type: Int
|
||||
) : Serializable {
|
||||
|
||||
companion object {
|
||||
const val TYPE_SHARE = 1
|
||||
const val TYPE_DOWNLOAD = 2
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
import com.cheng.bole.R
|
||||
|
||||
class VipTipItemEntity(var icon: Int, var name: String) {
|
||||
companion object {
|
||||
fun getVipTipList(): List<com.cheng.bole.bean.VipTipItemEntity> {
|
||||
val list = ArrayList<com.cheng.bole.bean.VipTipItemEntity>()
|
||||
list.add(com.cheng.bole.bean.VipTipItemEntity(R.mipmap.ic_vip_item1, "素材图库"))
|
||||
list.add(com.cheng.bole.bean.VipTipItemEntity(R.mipmap.ic_vip_item2, "魔方工具"))
|
||||
list.add(com.cheng.bole.bean.VipTipItemEntity(R.mipmap.ic_vip_item3, "高清图片"))
|
||||
list.add(com.cheng.bole.bean.VipTipItemEntity(R.mipmap.ic_vip_item4, "AI创作"))
|
||||
list.add(com.cheng.bole.bean.VipTipItemEntity(R.mipmap.ic_vip_item5, "视频提取"))
|
||||
list.add(com.cheng.bole.bean.VipTipItemEntity(R.mipmap.ic_vip_item6, "音频提取"))
|
||||
list.add(com.cheng.bole.bean.VipTipItemEntity(R.mipmap.ic_vip_item7, "文案提取"))
|
||||
list.add(com.cheng.bole.bean.VipTipItemEntity(R.mipmap.ic_vip_item8, "无广告"))
|
||||
list.add(com.cheng.bole.bean.VipTipItemEntity(R.mipmap.ic_vip_item9, "海量次数"))
|
||||
list.add(com.cheng.bole.bean.VipTipItemEntity(R.mipmap.ic_vip_item10, "海量流量"))
|
||||
list.add(com.cheng.bole.bean.VipTipItemEntity(R.mipmap.ic_vip_item11, "专属客服"))
|
||||
list.add(com.cheng.bole.bean.VipTipItemEntity(R.mipmap.ic_vip_item12, "在线浏览"))
|
||||
return list
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
class WxServiceEntity {
|
||||
var corpid = ""
|
||||
|
||||
@SerializedName("kf.address")
|
||||
var address = ""
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.cheng.bole.bean
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
data class WxShareEntity(
|
||||
val content: String = "",
|
||||
val image: String = "",
|
||||
val link: String = "",
|
||||
val title: String = ""
|
||||
) : Serializable
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package com.cheng.bole.common
|
||||
|
||||
import android.app.Activity
|
||||
import android.graphics.Color
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.azhon.appupdate.manager.DownloadManager
|
||||
import com.cheng.bole.BuildConfig
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.manager.UserConfigManager
|
||||
import com.cheng.bole.ui.dialog.UpdateVersionDialog
|
||||
import com.cheng.bole.utils.UIUtils
|
||||
import com.example.base.extensions.toast
|
||||
|
||||
object AppUpdate {
|
||||
|
||||
private val apkName = "appupdate.apk"
|
||||
|
||||
fun checkUpdate(fragment: Fragment, isManual: Boolean, clickFun: () -> Unit?) {
|
||||
|
||||
if (isManual) {
|
||||
toast(fragment.getString(R.string.check_version_ing))
|
||||
}
|
||||
|
||||
val result: com.cheng.bole.bean.VersionEntity? = UserConfigManager.userConfig?.config?.versionEntity
|
||||
result?.apply {
|
||||
if (UIUtils.checkVersion(version, BuildConfig.VERSION_NAME)) {
|
||||
if (last_version_force == BuildConfig.VERSION_NAME) {
|
||||
force = true
|
||||
} else if (UIUtils.checkVersion(last_version_force, BuildConfig.VERSION_NAME)) {
|
||||
force = true
|
||||
}
|
||||
clickFun.invoke()
|
||||
com.cheng.bole.common.AppUpdate.startUpdate(result, fragment)
|
||||
} else {
|
||||
if (isManual) {
|
||||
toast(fragment.getString(R.string.curr_new_version))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun startUpdate(versionEntity: com.cheng.bole.bean.VersionEntity, fragment: Fragment) {
|
||||
UpdateVersionDialog.newInstance(versionEntity).show(fragment.childFragmentManager, null)
|
||||
}
|
||||
|
||||
private fun startUpdateDialog(result: com.cheng.bole.bean.VersionEntity?, activity: Activity) {
|
||||
if (result == null) return
|
||||
val manager = DownloadManager.Builder(activity).run {
|
||||
apkUrl(result.url)
|
||||
apkName(com.cheng.bole.common.AppUpdate.apkName)
|
||||
smallIcon(R.mipmap.ic_launcher_icon)
|
||||
dialogImage(R.mipmap.ic_update_version_bg_z)
|
||||
showNewerToast(true)
|
||||
apkVersionName(result.version)
|
||||
apkSize(result.app_size)
|
||||
apkDescription(result.description)
|
||||
enableLog(true)
|
||||
jumpInstallPage(true)
|
||||
dialogButtonTextColor(Color.WHITE)
|
||||
showNotification(true)
|
||||
showBgdToast(false)
|
||||
when (result.force) {
|
||||
true -> forcedUpgrade(true)
|
||||
else -> forcedUpgrade(false)
|
||||
}
|
||||
dialogButtonColor(ContextCompat.getColor(activity, R.color.colorAccent))
|
||||
dialogProgressBarColor(ContextCompat.getColor(activity, R.color.colorAccent))
|
||||
notifyId(1011)
|
||||
build()
|
||||
}
|
||||
manager.download()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.cheng.bole.common
|
||||
|
||||
import android.graphics.Typeface
|
||||
import com.cheng.bole.BuildConfig
|
||||
import com.example.base.utils.Utils
|
||||
|
||||
object Constants {
|
||||
|
||||
const val BaseUrl = "http://bid7.yua8.cn"//正式地址
|
||||
const val TestUrl = "http://bid7.yua8.cn"//测试地址
|
||||
|
||||
const val APP_ID = "10055"
|
||||
|
||||
const val AppFilter = "${BuildConfig.APPLICATION_ID}.fileprovider"
|
||||
|
||||
const val WechatAppId = ""//微信APPID
|
||||
const val WechatAppSecret = ""//微信secret
|
||||
const val UmengAppkey = "692528cc8560e34872f36551"//友盟appKey
|
||||
|
||||
const val userAgreement = "$BaseUrl/static/new5/user.html"//用户协议
|
||||
const val privacyPolicy = "$BaseUrl/static/new5/provacy.html"//隐私政策
|
||||
const val renewAgreement = "$BaseUrl/static/new5/renew.html"//自动续费协议
|
||||
const val permissionList: String = "${BaseUrl}/static/new5/limits.html"//权限说明
|
||||
const val shareList: String = "${BaseUrl}/static/new5/shareList.html"//第三方共享清单
|
||||
const val sdkList: String = "${BaseUrl}/static/new5/sdkList.html"//第三方SDK目录
|
||||
|
||||
const val Encrypt = "zpzkfp72v3hgatzg5w7pyg86x5342kxt"
|
||||
const val Signature = "ckBHUSWBx3TqwNT2kxMrsXyXFuA3PW"
|
||||
|
||||
val almmsht = Typeface.createFromAsset(Utils.getApp().assets, "fonts/Alimama ShuHeiTi.ttf")
|
||||
val dDIN_PRO_M = Typeface.createFromAsset(Utils.getApp().assets, "fonts/D-DIN-PRO-500-Medium.otf")
|
||||
val youSheBiaoTiHei = Typeface.createFromAsset(Utils.getApp().assets, "fonts/YouSheBiaoTiHei.ttf")
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
package com.cheng.bole.common
|
||||
|
||||
object EventConstants {
|
||||
const val APP_LAUNCH = "client.launch" //app启动
|
||||
|
||||
const val GUIDE_LAUNCH = "client.guide.launch" //引导页启动
|
||||
|
||||
const val GUIDE_OPPORTUNITY_SCROLL = "client.guide.content.scroll" //滑动切换引导页内容
|
||||
|
||||
const val GUIDE_SKIP = "client.guide.pay.skip" //跳过引导页支付
|
||||
|
||||
const val HOME_BOTTOM_TAB_CHECK = "client.main.bottom.tab.check" //底部tab切换
|
||||
|
||||
const val HOME_NOTICE_CHECK = "client.main.notice.check" //首页通知点击
|
||||
|
||||
const val GOODS_SELECT = "client.goods.select" //点击切换支付的会员类型
|
||||
|
||||
const val PAY_SELECT = "client.pay.select" //点击切换支付类型
|
||||
|
||||
const val PAY_PAY = "client.pay.pay" //支付按钮点击
|
||||
|
||||
const val CHALLENGE_TASK_PAY_PAY = "client.challenge.task.pay.pay" //0元挑战支付按钮点击
|
||||
|
||||
const val PAY_SUCCESS = "client.pay.success" //支付成功
|
||||
|
||||
const val PAY_CANCEL = "client.pay.cancel" //支付取消
|
||||
|
||||
const val ERROR_CLIENT_WXPAY_ERR = "client.wxpay.err" //微信支付失败
|
||||
|
||||
const val ERROR_CLIENT_ALIPAY_ERR = "client.alipay.err" //支付宝支付失败
|
||||
|
||||
const val ERROR_CLIENT_DOWNLOAD_IMG = "client.download.img.err" //图片下载失败
|
||||
|
||||
const val ERROR_CLIENT_DOWNLOAD_VIDEO = "client.download.video.err" //视频下载失败
|
||||
|
||||
const val ERROR_CLIENT_DOWNLOAD_AUDIO = "client.download.audio.err" //音频下载失败
|
||||
|
||||
const val CANCEL_DOWNLOAD_VIDEO = "client.download.video.cancel" //取消视频下载
|
||||
|
||||
const val PAUSE_DOWNLOAD_VIDEO = "client.download.video.pause" //暂停视频下载
|
||||
|
||||
const val CONTINUE_DOWNLOAD_VIDEO = "client.download.video.continue" //继续视频下载
|
||||
|
||||
const val RESTART_DOWNLOAD_VIDEO = "client.download.video.restart" //重新视频下载
|
||||
|
||||
const val SPEED_UP_DOWNLOAD_VIDEO = "client.download.video.speed.up" //加速视频下载
|
||||
|
||||
const val BACKGROUND_CLIENT_DOWNLOAD = "client.download.background" //后台下载
|
||||
|
||||
const val FLOAT_WINDOW_CLICK = "client.float.window.click" //点击悬浮窗
|
||||
|
||||
const val SAVE_AI_MEDIA = "client.ai.media.save" //ai生成文件保存
|
||||
|
||||
const val RECOGNIZE_AUDIO_TO_TEXT = "client.audio.text.recognize" //音频转文字
|
||||
|
||||
const val PKG_UPDATE = "client.pkg.update" //升级弹窗点击更新
|
||||
|
||||
const val PKG_CANCEL = "client.pkg.cancel" //升级弹窗点击取消
|
||||
|
||||
const val GET_MATERIAL = "client.get.material" //获取素材
|
||||
|
||||
const val GET_MATERIAL_CANCEL = "client.get.material.cancel" //取消获取素材
|
||||
|
||||
const val DIALOG_CONFIRM_SAVE_FILE = "client.dialog.confirm.save.file" //保存文件地址弹框确认
|
||||
|
||||
const val DIALOG_GO_TO_VIEW = "client.dialog.go.to.view" //前往保存文件的地址查看
|
||||
|
||||
const val JUMP_TO_ABOUT_US = "client.jump.to.about.us" //界面跳转
|
||||
|
||||
const val JUMP_TO_LINK_EXTRACT = "client.jump.to.link.extract" //跳转链接提取
|
||||
|
||||
const val JUMP_TO_WECHAT_VIDEO = "client.jump.to.wechat.video" //跳转视频号
|
||||
|
||||
const val JUMP_TO_WECHAT_PLAYBACK = "client.jump.to.wechat.video.playback" //跳转直播回放
|
||||
|
||||
const val JUMP_TO_COURSE_WX_VIDEO = "client.course.wechat.video" //视频号视频教程
|
||||
|
||||
const val JUMP_TO_COURSE_PLAYBACK = "client.course.playback" //直播回放视频教程
|
||||
|
||||
const val JUMP_TO_TOOL = "client.jump.to.home.tool" //跳转工具
|
||||
|
||||
const val MAIN_CENTER_ENABLE = "client.main.center.enable" //首页跳转个人中心
|
||||
|
||||
const val JUMP_TO_MEMBER_RECHARGE = "client.jump.to.member.recharge" //跳转到充值页
|
||||
|
||||
const val JUMP_TO_LOGIN = "client.jump.to.login" //跳转到登录页
|
||||
|
||||
const val JUMP_TO_SYSTEM_SETTING = "client.jump.to.system.setting" //跳转到系统设置
|
||||
|
||||
const val JUMP_TO_USER_SETTING = "client.jump.to.user.setting" //跳转到用户设置
|
||||
|
||||
const val JUMP_TO_FEEDBACK = "client.jump.to.feedback" //跳转到意见反馈
|
||||
|
||||
const val JUMP_TO_ACCOUNT_BIND = "client.jump.to.account.bind" //跳转到账号绑定
|
||||
|
||||
const val JUMP_TO_ACCOUNT_MANAGE = "client.jump.to.account.manage" //跳转到账号管理
|
||||
|
||||
const val JUMP_TO_DOWNLOAD_HISTORY = "client.jump.to.download.history" //跳转到下载记录
|
||||
|
||||
const val JUMP_TO_DOWNLOAD_TASK_LIST = "client.jump.to.download.task.list" //跳转到下载任务列表
|
||||
|
||||
const val JUMP_TO_RECHARGE_DIAMOND = "client.jump.to.recharge.diamond" //跳转到M币充值
|
||||
|
||||
const val JUMP_TO_COUPON_LIST = "client.jump.to.coupon.list" //跳转优惠券列表
|
||||
|
||||
const val JUMP_TO_CHALLENGE_TASK = "client.jump.to.challenge.task" //跳转到0元挑战
|
||||
|
||||
const val JUMP_TO_SHARE_WX_VIDEO = "client.jump.to.wechat.share.video" //跳转到视频号分享
|
||||
|
||||
const val JUMP_TO_SHARE_WX_PLAYBACK = "client.jump.to.wechat.share.playback" //跳转到直播回放分享
|
||||
|
||||
const val JUMP_TO_COURSE = "client.jump.to.course" //跳转到指导教程
|
||||
|
||||
const val DOWNLOAD_FILE = "client.download.file" //下载文件
|
||||
|
||||
const val DOWNLOAD_FILE_SUCCESS = "client.download.file.success" //下载文件成功
|
||||
|
||||
const val DOWNLOAD_FILE_ERROR = "client.download.file.error" //下载文件失败
|
||||
|
||||
const val TRANSPOND_FILE = "client.transpond.file" //转发文件
|
||||
|
||||
const val MATERIAL_COPY_TEXT = "client.material.copy.text" //复制文字
|
||||
|
||||
const val MATERIAL_TYPE_CHECK = "client.material.type.check" //素材切换
|
||||
|
||||
const val MATERIAL_ALL_SELECT = "client.material.all.select" //全部选中素材
|
||||
|
||||
const val MATERIAL_SELECT = "client.material.select" //选择素材
|
||||
|
||||
const val TOOLS_VIDEO_EXTRACT_AUDIO = "client.tools.video.audio" //提取音频
|
||||
|
||||
const val MATERIAL_PLAY_VIDEO = "client.material.play.video" //播发视频
|
||||
|
||||
const val GET_CODE = "client.get.code" //获取验证码
|
||||
|
||||
const val LOGIN = "client.login" //登录
|
||||
|
||||
const val SWITCH_ACCOUNT = "client.switch.account" //切换账户
|
||||
|
||||
const val ACCOUNT_BIND = "client.account.bind" //绑定账号
|
||||
|
||||
const val ACCOUNT_BIND_CANCEL = "client.account.bind.cancel" //取消绑定账号
|
||||
|
||||
const val CHECK_AGREEMENT = "client.check.agreement" //切换协议状态
|
||||
|
||||
const val VIEW_AGREEMENT = "client.view.agreement" //查看用户协议
|
||||
|
||||
const val PRIVACY_POLICY_CLICK_OK = "client.privacy.policy.click.ok" //同意隐私协议
|
||||
|
||||
const val SAVE_USER_CONFIG_ERROR = "client.save.user.config.error" //保存用户配置错误
|
||||
|
||||
const val SHARE_APP = "client.share.app" //分享app
|
||||
|
||||
const val CLEAR_CACHE = "client.clear.cache" //清除缓存
|
||||
|
||||
const val CONTACT_SERVICE = "client.contact.service" //联系客服
|
||||
|
||||
const val EXIT_LOGIN = "client.exit.login" //退出登录
|
||||
|
||||
const val CANCEL_ACCOUNT = "client.cancel.account" //注销账户
|
||||
|
||||
const val MEMBER_FORCE_LOGIN = "client.member.force.login" //会员强制登录
|
||||
|
||||
const val GET_MATERIAL_TIMES_USE_UP = "client.times.use.up.get.material" //获取素材次数已用完
|
||||
|
||||
const val PICTURE_HANDLE_TIMES_USE_UP = "client.times.use.up.picture.handle" //图片处理次数已用完
|
||||
|
||||
const val CHECK_LOGIN_TYPE = "client.check.login.type" //切换登录方式
|
||||
|
||||
const val OPEN_SCREEN_AD_SHOW = "client.ad.open.screen.show" //开屏广告展示
|
||||
|
||||
const val OPEN_SCREEN_AD_SKIP = "client.ad.open.screen.skip" //开屏广告跳过
|
||||
|
||||
const val OPEN_SCREEN_AD_CLICK = "client.ad.open.screen.click" //开屏广告点击
|
||||
|
||||
const val BANNER_AD_SHOW = "client.ad.banner.show" //banner广告展示
|
||||
|
||||
const val BANNER_AD_CLOSE = "client.ad.banner.close" //banner广告关闭
|
||||
|
||||
const val BANNER_AD_CLICK = "client.ad.banner.click" //banner广告点击
|
||||
|
||||
const val INSERT_SCREEN_AD_SHOW = "client.ad.insert.screen.show" //插屏广告展示
|
||||
|
||||
const val INSERT_SCREEN_AD_CLOSE = "client.ad.insert.screen.close" //插屏广告关闭
|
||||
|
||||
const val INSERT_SCREEN_AD_CLICK = "client.ad.insert.screen.click" //插屏广告点击
|
||||
|
||||
const val INSERT_SCREEN_AD_SKIP_VIDEO = "client.ad.insert.screen.skip.video" //跳过插屏广告
|
||||
|
||||
const val INCENTIVE_AD_SHOW = "client.ad.incentive.show" //激励广告展示
|
||||
|
||||
const val INCENTIVE_AD_CLOSE = "client.ad.incentive.close" //激励广告关闭
|
||||
|
||||
const val INCENTIVE_AD_REWARD = "client.ad.incentive.reward" //激励广告已获取到奖励
|
||||
|
||||
const val INCENTIVE_AD_SKIP_VIDEO = "client.ad.incentive.skip.video" //跳过激励广告
|
||||
|
||||
const val ACCOUNT_UNBIND = "client.account.unbind" //解除绑定账号
|
||||
|
||||
const val HISTORY_RECORD_TYPE_CHECK = "client.history.record.type.check" //历史记录切换
|
||||
|
||||
const val CLOSE_FREE_TIME_USES_UP_DIALOG =
|
||||
"client.free.time.uses.up.dialog.close" //关闭免费次数用完的提示框
|
||||
|
||||
const val CHECK_FREE_TIME_USES_UP_DIALOG =
|
||||
"client.free.time.uses.up.dialog.check" //免费次数用完的提示框切换充值类型
|
||||
|
||||
const val CONFIRM_FREE_TIME_USES_UP_DIALOG =
|
||||
"client.free.time.uses.up.dialog.confirm" //确认免费次数用完的提示框
|
||||
|
||||
const val MULTI_DELETE_FILE = "client.multi.delete.file" //批量删除文件
|
||||
|
||||
const val MULTI_TRANSMIT_FILE = "client.multi.transmit.file" //批量转发文件
|
||||
|
||||
const val PREVIEW_DELETE_FILE = "client.preview.delete.file" //预览时删除文件
|
||||
|
||||
const val PREVIEW_TRANSMIT_FILE = "client.preview.transmit.file" //预览时删除文件
|
||||
|
||||
const val PREVIEW_HANDLE_IMAGE = "client.preview.handle.image" //预览时进行图片处理
|
||||
|
||||
const val TOOLS_HANDLE_IMAGE_START = "client.tools.handle.image.start" //图片处理开始
|
||||
|
||||
const val TOOLS_HANDLE_SAVE_IMAGE = "client.tools.handle.save.image" //保存已处理过的图片至相册
|
||||
|
||||
const val AUTO_SWITCH_DOWNLOAD_URL = "client.auto.switch.download.url" //自动切换下载链接
|
||||
|
||||
const val HAND_SWITCH_DOWNLOAD_URL = "client.hand.switch.download.url" //手动切换下载链接立即加速
|
||||
|
||||
const val HOME_BANNER_CLICK = "client.home.banner.click"
|
||||
|
||||
const val COUPON_ANIMATION_PLAY = "client.coupon.animation.play" //播放优惠券动画
|
||||
|
||||
const val COUPON_ANIMATION_CLOSE = "client.coupon.animation.close" //关闭优惠券动画
|
||||
|
||||
const val COUPON_RECEIVE = "client.coupon.receive" //领取优惠券
|
||||
|
||||
const val COUPON_REDEEM_ENABLE = "client.coupon.redeem.enable" //优惠券兑换按钮点击
|
||||
|
||||
const val COUPON_REDEEM_INFO = "client.coupon.redeem.info" //优惠券兑换详情
|
||||
|
||||
const val COUPON_REDEEM = "client.coupon.redeem" //优惠券兑换
|
||||
|
||||
const val COUPON_REDEEM_SUCCESS = "client.coupon.redeem.success" //优惠券兑换成功
|
||||
|
||||
const val COUPON_REDEEM_SUCCESS_CONFIRM = "client.coupon.redeem.success.confirm" //优惠券兑换成功
|
||||
|
||||
const val COUPON_VIEW = "client.coupon.view" //查看优惠券
|
||||
|
||||
const val COUPON_DIALOG_CHECK = "client.coupon.dialog.check" //切换优惠券
|
||||
|
||||
const val COUPON_DIALOG_CLOSE = "client.coupon.dialog.close" //关闭优惠券
|
||||
|
||||
const val COUPON_DIALOG_CONFIRM = "client.coupon.dialog.confirm" //确认优惠券
|
||||
|
||||
const val COPY_USER_ID = "client.copy_user_id" //复制用户id
|
||||
|
||||
const val SHOW_PALYBACK_HINT_DIALOG = "client.show.playback.hint.dialog"
|
||||
|
||||
const val EXIT_APP = "client.exit.app" //退出APP
|
||||
|
||||
const val SHOW_DIALOG = "client.show.dialog" //弹出退出app的弹框
|
||||
|
||||
const val START_COUPON_ANIMATION = "client.start.coupon.animation"
|
||||
|
||||
const val CHALLENGE_TASK_SIGN_IN = "client.challenge.tasK.sign.in" //签到
|
||||
|
||||
const val CHALLENGE_TASK_SIGN_IN_SUCCESS = "client.challenge.tasK.sign.in.success" //签到成功
|
||||
|
||||
const val CHALLENGE_TASK_SIGN_IN_FAIL = "client.challenge.tasK.sign.in.fail" //签到失败
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.cheng.bole.event
|
||||
|
||||
class ClipboardEvent(var text: String)
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.cheng.bole.event
|
||||
|
||||
import com.ylqh.cube.bean.CouponActivityEntity
|
||||
|
||||
class CouponActivityEvent(var list: List<CouponActivityEntity>, var type: Int)// 0 首页, 1 enter, 2 exit
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package com.cheng.bole.event
|
||||
|
||||
class CouponRefreshEvent {
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package com.cheng.bole.event
|
||||
|
||||
class HomeRefreshEvent {
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package com.cheng.bole.event
|
||||
|
||||
class LoginSuccessEvent {
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package com.cheng.bole.event
|
||||
|
||||
class LogoutSuccessEvent {
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package com.cheng.bole.event
|
||||
|
||||
class MineRefreshEvent {
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.cheng.bole.event
|
||||
|
||||
enum class PayStatusEnum {
|
||||
PAY_SUCCESS, PAY_ERROR, PAY_CANCEL
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.cheng.bole.event
|
||||
|
||||
class PayStatusEvent(var payStatus: com.cheng.bole.event.PayStatusEnum, var message: String = "")
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package com.cheng.bole.event
|
||||
|
||||
class PushMessageEvent(
|
||||
var payload: String,
|
||||
var type: Int //2展示通知 3点击通知
|
||||
)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package com.cheng.bole.event
|
||||
|
||||
class UserInfoEvent {
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package com.cheng.bole.event
|
||||
|
||||
class VipPaySuccessEvent {
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.cheng.bole.event
|
||||
|
||||
class WxLoginEvent(var code: String, var state: String)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.cheng.bole.ext
|
||||
|
||||
import java.text.DecimalFormat
|
||||
|
||||
fun Number.format(pattern: String = "0.##"): String {
|
||||
return DecimalFormat(pattern).format(this)
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.cheng.bole.ext
|
||||
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
|
||||
fun String.format(newScale: Int = 2, roundingMode: RoundingMode = RoundingMode.HALF_UP): BigDecimal {
|
||||
val bd = BigDecimal(this)
|
||||
return bd.setScale(newScale, roundingMode)
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.cheng.bole.ext
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.TimeInterpolator
|
||||
import android.animation.ValueAnimator
|
||||
import android.view.animation.AccelerateDecelerateInterpolator
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
|
||||
fun ViewPager2.setCurrentItem(
|
||||
item: Int,
|
||||
duration: Long,
|
||||
interpolator: TimeInterpolator = AccelerateDecelerateInterpolator(),
|
||||
pagePxWidth: Int = width,
|
||||
pagePxHeight: Int = height
|
||||
) {
|
||||
val pxToDrag: Int = if (orientation == ViewPager2.ORIENTATION_HORIZONTAL) pagePxWidth * (item - currentItem) else pagePxHeight * (item - currentItem)
|
||||
val animator = ValueAnimator.ofInt(0, pxToDrag)
|
||||
var previousValue = 0
|
||||
animator.addUpdateListener { valueAnimator ->
|
||||
val currentValue = valueAnimator.animatedValue as Int
|
||||
val currentPxToDrag = (currentValue - previousValue).toFloat()
|
||||
fakeDragBy(-currentPxToDrag)
|
||||
previousValue = currentValue
|
||||
}
|
||||
animator.addListener(object : Animator.AnimatorListener {
|
||||
override fun onAnimationStart(animation: Animator) { beginFakeDrag() }
|
||||
override fun onAnimationEnd(animation: Animator) { endFakeDrag() }
|
||||
override fun onAnimationCancel(animation: Animator) { /* Ignored */ }
|
||||
override fun onAnimationRepeat(animation: Animator) { /* Ignored */ }
|
||||
})
|
||||
animator.interpolator = interpolator
|
||||
animator.duration = duration
|
||||
animator.start()
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.cheng.bole.impl
|
||||
|
||||
import android.widget.SeekBar
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener
|
||||
|
||||
abstract class OnSeekBarChangeListenerImpl: OnSeekBarChangeListener {
|
||||
|
||||
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
|
||||
|
||||
}
|
||||
|
||||
override fun onStartTrackingTouch(seekBar: SeekBar?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar?) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.cheng.bole.impl
|
||||
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
|
||||
abstract class TextWatcherImpl: TextWatcher {
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package com.cheng.bole.manager
|
||||
|
||||
enum class DialogEnum {
|
||||
CLICK_OK,
|
||||
CLICK_CANCEL
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package com.cheng.bole.manager
|
||||
|
||||
import com.alibaba.fastjson.JSONObject
|
||||
import com.cheng.bole.net.ApiFactory
|
||||
import com.example.base.utils.L
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
|
||||
object EventReportManager {
|
||||
|
||||
fun eventReport(key: String?, value: String?, extra: String) {
|
||||
GlobalScope.launch {
|
||||
try {
|
||||
val jsonObject = JSONObject()
|
||||
jsonObject["source"] = "android"
|
||||
jsonObject["type"] = "click"
|
||||
jsonObject["key"] = key//点击的地方
|
||||
jsonObject["value"] = value
|
||||
jsonObject["extra"] = extra//附加参数
|
||||
L.d("TAG-->>${jsonObject}")
|
||||
ApiFactory.apiService.eventReport(jsonObject.toString().toRequestBody("application/json".toMediaType()))
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package com.cheng.bole.manager
|
||||
|
||||
import com.example.base.utils.MMKVUtils
|
||||
|
||||
object LoginManager {
|
||||
|
||||
fun saveToken(token: String) {
|
||||
MMKVUtils.put("x-token", token)
|
||||
}
|
||||
|
||||
fun getToken(): String {
|
||||
return MMKVUtils.getString("x-token") ?: ""
|
||||
}
|
||||
|
||||
fun isLogin(): Boolean {
|
||||
return !UserConfigManager.getIsTemp()
|
||||
}
|
||||
|
||||
fun saveLastLoginType(type: String) {
|
||||
MMKVUtils.put("last_login_type", type)
|
||||
}
|
||||
|
||||
fun getLastLoginType(): String? {
|
||||
return MMKVUtils.getString("last_login_type")
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
fun logout() {
|
||||
// 1. 清除用户数据
|
||||
MMKVUtils.put("x-role", true)
|
||||
MMKVUtils.removeKey("userConfig")
|
||||
MMKVUtils.removeKey("x-token")
|
||||
MMKVUtils.removeKey("guide_pay")
|
||||
MMKVUtils.removeKey("guide")
|
||||
MMKVUtils.removeKey("nologin_pay")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
package com.cheng.bole.manager
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.provider.Settings
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.ui.dialog.TipDialog
|
||||
import com.example.base.extensions.toast
|
||||
import com.example.base.utils.Utils
|
||||
|
||||
|
||||
object NotificationHelper {
|
||||
private val notificationManager by lazy { Utils.getApp().getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager }
|
||||
|
||||
private const val DEFAULT_CHANNEL_ID = "default"
|
||||
private const val DOWNLOAD_CHANNEL_ID = "download"
|
||||
private const val FOREGROUND_CHANNEL_ID = "foreground"
|
||||
|
||||
private const val DOWNLOAD_GROUP = "download_group"
|
||||
|
||||
private const val DOWNLOAD_CANCEL_CODE = 2000
|
||||
private const val DOWNLOAD_RETRY_CODE = 3000
|
||||
|
||||
private var _notificationId = 1000
|
||||
|
||||
/**
|
||||
* 创建默认通知通道
|
||||
*/
|
||||
fun createDefaultChannel() {
|
||||
createNotificationChannel(DEFAULT_CHANNEL_ID, "Default", NotificationManager.IMPORTANCE_DEFAULT)
|
||||
}
|
||||
|
||||
/**
|
||||
* 前台通知
|
||||
*/
|
||||
fun startForeground(service: Service) {
|
||||
val channelId = createNotificationChannel(FOREGROUND_CHANNEL_ID, "Foreground", NotificationManager.IMPORTANCE_LOW)
|
||||
val builder = NotificationCompat.Builder(service, channelId)
|
||||
val notification = builder
|
||||
.setContentText("文件下载服务运行中")
|
||||
.setSmallIcon(R.mipmap.ic_launcher_icon)
|
||||
.setCategory(Notification.CATEGORY_SERVICE)
|
||||
.build()
|
||||
service.startForeground(1, notification)
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消通知
|
||||
*/
|
||||
fun cancelNotification(id: Int) {
|
||||
notificationManager.cancel(id)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建通知通道
|
||||
*
|
||||
* @param channelId
|
||||
* @param channelName
|
||||
* @return
|
||||
*/
|
||||
private fun createNotificationChannel(channelId: String, channelName: String, importance: Int): String {
|
||||
val channel = NotificationChannel(channelId, channelName, importance)
|
||||
channel.setSound(null, null)
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
return channelId
|
||||
}
|
||||
|
||||
fun getNotificationId(): Int {
|
||||
return ++_notificationId
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断通知权限是否开启
|
||||
*/
|
||||
fun isNotificationEnabled(context: Context): Boolean {
|
||||
return NotificationManagerCompat.from(context).areNotificationsEnabled()
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知被禁用时显示提示
|
||||
*/
|
||||
fun showDisabledTip(activity: Activity, fm: FragmentManager, isHomePage: Boolean = false) {
|
||||
if (isHomePage) {
|
||||
toast("平台推送消息需要通知权限,检测到您已关闭相关权限,请前往设置手动打开")
|
||||
} else {
|
||||
val f = TipDialog.newInstance("请开启通知权限", "为方便查看下载进度,请在设置中打开【允许通知】")
|
||||
f.setOnSelectListener {
|
||||
if (it == DialogEnum.CLICK_OK) {
|
||||
try {
|
||||
//8.0及以上
|
||||
val intent = Intent()
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
|
||||
intent.putExtra(Settings.EXTRA_APP_PACKAGE, activity.packageName)
|
||||
activity.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
val intent = Intent()
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
||||
intent.setData(Uri.fromParts("package", activity.packageName, null))
|
||||
activity.startActivity(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
f.show(fm, TipDialog::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
package com.cheng.bole.manager
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.text.TextUtils
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.cheng.bole.R
|
||||
import com.example.base.extensions.toast
|
||||
import com.umeng.socialize.ShareAction
|
||||
import com.umeng.socialize.UMShareListener
|
||||
import com.umeng.socialize.bean.SHARE_MEDIA
|
||||
import com.umeng.socialize.media.UMImage
|
||||
import com.umeng.socialize.media.UMVideo
|
||||
import com.umeng.socialize.media.UMWeb
|
||||
import java.io.File
|
||||
|
||||
|
||||
object ShareManager {
|
||||
|
||||
/**
|
||||
* 分享媒体文件
|
||||
*/
|
||||
fun shareFile(context: Context, file: File) {
|
||||
val uri = FileProvider.getUriForFile(context,"${context.packageName}.fileprovider", file)
|
||||
val intent = Intent(Intent.ACTION_SEND)
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
intent.putExtra(Intent.EXTRA_STREAM, uri)
|
||||
intent.setType(if (file.extension == "mp4") "video/mp4" else if (file.extension == "mp3") "audio/x-mpeg" else "image/jpeg") //分享文件类型
|
||||
context.startActivity(Intent.createChooser(intent, "分享"))
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享
|
||||
*/
|
||||
fun shareUrl(
|
||||
activity: FragmentActivity,
|
||||
shareMedia: SHARE_MEDIA,
|
||||
shareBean: com.cheng.bole.bean.WxShareEntity,
|
||||
clickFun: () -> Unit,
|
||||
) {
|
||||
if (!TextUtils.isEmpty(shareBean.link)) {
|
||||
val web = UMWeb(shareBean.link)
|
||||
web.title = shareBean.title
|
||||
web.setThumb(UMImage(activity, R.mipmap.ic_launcher_icon))
|
||||
web.description = shareBean.content
|
||||
|
||||
ShareAction(activity).withMedia(web).setPlatform(shareMedia)
|
||||
.setCallback(object : UMShareListener {
|
||||
/**
|
||||
* 分享成功的回调
|
||||
* @param platform 平台类型
|
||||
*/
|
||||
override fun onResult(platform: SHARE_MEDIA) {
|
||||
clickFun.invoke()
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享取消的回调
|
||||
* @param platform 平台类型
|
||||
*/
|
||||
override fun onCancel(platform: SHARE_MEDIA) {
|
||||
toast("取消分享")
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享失败的回调
|
||||
* @param platform 平台类型
|
||||
* @param t 错误原因
|
||||
*/
|
||||
override fun onError(platform: SHARE_MEDIA, t: Throwable) {
|
||||
toast("分享失败,请重试")
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享开始的回调
|
||||
* @param platform 平台类型
|
||||
*/
|
||||
override fun onStart(platform: SHARE_MEDIA) {}
|
||||
|
||||
}).share()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun shareImageOnWeChat(activity: Activity, image: UMImage) {
|
||||
image.title = ""
|
||||
image.description = ""
|
||||
image.setThumb(image)
|
||||
ShareAction(activity).withMedia(image).withText("")
|
||||
.setPlatform(SHARE_MEDIA.WEIXIN)
|
||||
.setCallback(object : UMShareListener {
|
||||
/**
|
||||
* 分享成功的回调
|
||||
* @param platform 平台类型
|
||||
*/
|
||||
override fun onResult(platform: SHARE_MEDIA) {
|
||||
toast("分享成功")
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享取消的回调
|
||||
* @param platform 平台类型
|
||||
*/
|
||||
override fun onCancel(platform: SHARE_MEDIA) {
|
||||
toast("取消分享")
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享失败的回调
|
||||
* @param platform 平台类型
|
||||
* @param t 错误原因
|
||||
*/
|
||||
override fun onError(platform: SHARE_MEDIA, t: Throwable) {
|
||||
toast("分享失败,请重试")
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享开始的回调
|
||||
* @param platform 平台类型
|
||||
*/
|
||||
override fun onStart(platform: SHARE_MEDIA) {}
|
||||
|
||||
}).share()
|
||||
}
|
||||
|
||||
fun shareFileOnWeChat(activity: Activity, file: File) {
|
||||
val video = UMVideo(file)
|
||||
ShareAction(activity).withMedia(video)
|
||||
.setPlatform(SHARE_MEDIA.WEIXIN)
|
||||
.setCallback(object : UMShareListener {
|
||||
/**
|
||||
* 分享成功的回调
|
||||
* @param platform 平台类型
|
||||
*/
|
||||
override fun onResult(platform: SHARE_MEDIA) {
|
||||
toast("分享成功")
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享取消的回调
|
||||
* @param platform 平台类型
|
||||
*/
|
||||
override fun onCancel(platform: SHARE_MEDIA) {
|
||||
toast("取消分享")
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享失败的回调
|
||||
* @param platform 平台类型
|
||||
* @param t 错误原因
|
||||
*/
|
||||
override fun onError(platform: SHARE_MEDIA, t: Throwable) {
|
||||
toast("分享失败,请重试")
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享开始的回调
|
||||
* @param platform 平台类型
|
||||
*/
|
||||
override fun onStart(platform: SHARE_MEDIA) {}
|
||||
|
||||
}).share()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
package com.cheng.bole.manager
|
||||
|
||||
import android.os.Build
|
||||
import android.text.TextUtils
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.example.base.extensions.toast
|
||||
import com.example.base.utils.MMKVUtils
|
||||
import com.example.base.utils.Utils
|
||||
import com.github.gzuliyujiang.oaid.DeviceID
|
||||
import com.github.gzuliyujiang.oaid.DeviceIdentifier
|
||||
import com.github.gzuliyujiang.oaid.IGetter
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.cheng.bole.net.ApiFactory
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.json.JSONObject
|
||||
|
||||
object UserConfigManager {
|
||||
val _userConfigLiveData = MutableLiveData<com.cheng.bole.bean.UserConfigEntity?>()
|
||||
|
||||
val userConfig: com.cheng.bole.bean.UserConfigEntity? get() = _userConfigLiveData.value
|
||||
|
||||
val userInfoLiveData = MutableLiveData<com.cheng.bole.bean.UserEntity?>()
|
||||
|
||||
val userInfo: com.cheng.bole.bean.UserEntity? get() = userInfoLiveData.value
|
||||
|
||||
fun getUserConfig(clickFun: () -> Unit?) {
|
||||
if (!TextUtils.isEmpty(MMKVUtils.getString("userConfig"))) {
|
||||
val data = Gson().fromJson(MMKVUtils.getString("userConfig"), com.cheng.bole.bean.UserConfigEntity::class.java)
|
||||
_userConfigLiveData.postValue(data)
|
||||
|
||||
getOaId()
|
||||
saveUserConfig(data)
|
||||
clickFun.invoke()
|
||||
return
|
||||
}
|
||||
getOaId {
|
||||
userConfig { clickFun.invoke() }
|
||||
}
|
||||
}
|
||||
|
||||
fun userConfig(clickFun: () -> Unit?) {
|
||||
GlobalScope.launch {
|
||||
try {
|
||||
val oaid = MMKVUtils.getString("oaid") ?: ""
|
||||
val response = ApiFactory.apiService.getUserConfig(oaid, Build.VERSION.SDK_INT, "", DeviceIdentifier.getAndroidID(Utils.getApp()), getGTCid())
|
||||
if (response.status) {
|
||||
_userConfigLiveData.postValue(response.data)
|
||||
MMKVUtils.put("userConfig", Gson().toJson(response.data))
|
||||
|
||||
saveUserConfig(response.data)
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
clickFun.invoke()
|
||||
}
|
||||
} else {
|
||||
withContext(Dispatchers.Main) {
|
||||
toast(response.message, true)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveUserConfig(data: com.cheng.bole.bean.UserConfigEntity) {
|
||||
try {
|
||||
LoginManager.saveToken(data.token)
|
||||
saveIsTemp(data.temp)
|
||||
if (data.config != null){
|
||||
saveGuidePayEnable(data.config!!.guidePayEnable!!)
|
||||
saveGuideEnable(data.config!!.guideEnable!!)
|
||||
saveGuideHint(data.config!!.guideHint)
|
||||
saveNoLoginPay(data.config!!.noLoginPayEnable!!)
|
||||
savePayAgreementEnable(data.config!!.payAgreementEnable!!)
|
||||
saveLoginType(data.config!!.loginType!!)
|
||||
saveBanners(data.config!!.banners!!)
|
||||
saveShareEntity(data.config!!.wxShareEntity)
|
||||
saveAdSwitch(data.config!!.adSwitch)
|
||||
saveServicePhoneList(data.config!!.servicePhoneList)
|
||||
}
|
||||
} catch (e : Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
fun saveLastUserinfo(userinfo: com.cheng.bole.bean.UserEntity?) {
|
||||
MMKVUtils.put("last_userinfo", Gson().toJson(userinfo))
|
||||
}
|
||||
|
||||
fun getLastUserinfo(): com.cheng.bole.bean.UserEntity? {
|
||||
val str = MMKVUtils.getString("last_userinfo")
|
||||
if (!TextUtils.isEmpty(str)) {
|
||||
return Gson().fromJson(str, com.cheng.bole.bean.UserEntity::class.java)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun saveGuidePayEnable(temp: Boolean) {
|
||||
MMKVUtils.put("guide_pay", temp)//引导页是否可以支付
|
||||
}
|
||||
|
||||
fun getGuidePayEnable(): Boolean {
|
||||
return MMKVUtils.getBoolean("guide_pay", true)
|
||||
}
|
||||
|
||||
private fun saveGuideEnable(temp: Boolean) {
|
||||
MMKVUtils.put("guide", temp)//是否开启引导页
|
||||
}
|
||||
|
||||
fun getGuideEnable(): Boolean {
|
||||
return MMKVUtils.getBoolean("guide", true)
|
||||
}
|
||||
|
||||
private fun saveGuideHint(hint: String?) {
|
||||
MMKVUtils.put("guide_hint", hint)
|
||||
}
|
||||
|
||||
fun getGuideHint(): String {
|
||||
return MMKVUtils.getString("guide_hint") ?: ""
|
||||
}
|
||||
|
||||
fun saveIsTemp(temp: Boolean) {
|
||||
MMKVUtils.put("x-role", temp)//true临时用户 ,false登录用户
|
||||
}
|
||||
|
||||
fun getIsTemp(): Boolean {
|
||||
return MMKVUtils.getBoolean("x-role", true)
|
||||
}
|
||||
|
||||
fun isFirstUseApp(): Boolean {
|
||||
return MMKVUtils.getBoolean("isFirstUse", true)
|
||||
}
|
||||
|
||||
fun saveFirstUseApp(isFirst: Boolean) {
|
||||
MMKVUtils.put("isFirstUse", isFirst)
|
||||
}
|
||||
|
||||
private fun saveNoLoginPay(noLoginPay: Boolean) {
|
||||
MMKVUtils.put("nologin_pay", noLoginPay)
|
||||
}
|
||||
|
||||
fun getNoLoginPay(): Boolean {
|
||||
return MMKVUtils.getBoolean("nologin_pay", true)
|
||||
}
|
||||
|
||||
private fun savePayAgreementEnable(payAgreement: Boolean) {
|
||||
MMKVUtils.put("pay_agreement", payAgreement)
|
||||
}
|
||||
|
||||
fun isPayAgreementEnable(): Boolean {
|
||||
return MMKVUtils.getBoolean("pay_agreement", true)
|
||||
}
|
||||
|
||||
private fun saveLoginType(list: List<String>) {
|
||||
MMKVUtils.put("login_type", Gson().toJson(list))
|
||||
}
|
||||
|
||||
fun getLoginType(): List<String> {
|
||||
val s = MMKVUtils.getString("login_type")
|
||||
if (!TextUtils.isEmpty(s)) {
|
||||
return Gson().fromJson(s, object : TypeToken<List<String>>() {}.type)
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
private fun saveBanners(list: List<com.cheng.bole.bean.BannerEntity>) {
|
||||
MMKVUtils.put("home_banner", Gson().toJson(list))
|
||||
}
|
||||
|
||||
fun getBanners(): List<com.cheng.bole.bean.BannerEntity> {
|
||||
val s = MMKVUtils.getString("home_banner")
|
||||
if (!TextUtils.isEmpty(s)) {
|
||||
return Gson().fromJson(s, object : TypeToken<List<com.cheng.bole.bean.BannerEntity>>() {}.type)
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
private fun saveShareEntity(entity: com.cheng.bole.bean.WxShareEntity?) {
|
||||
MMKVUtils.put("weixin_share", Gson().toJson(entity))
|
||||
}
|
||||
|
||||
fun getShareEntity(): com.cheng.bole.bean.WxShareEntity? {
|
||||
val s = MMKVUtils.getString("weixin_share")
|
||||
if (!TextUtils.isEmpty(s)) {
|
||||
return Gson().fromJson(s, com.cheng.bole.bean.WxShareEntity::class.java)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun saveAdSwitch(switch: Boolean) {
|
||||
MMKVUtils.put("ad_switch", switch)
|
||||
}
|
||||
|
||||
fun isAdSwitch(): Boolean {
|
||||
return MMKVUtils.getBoolean("ad_switch")
|
||||
}
|
||||
|
||||
private fun saveServicePhoneList(list: List<String>) {
|
||||
MMKVUtils.put("service_phone_list", Gson().toJson(list))
|
||||
}
|
||||
|
||||
fun getServicePhoneList(): List<String> {
|
||||
val str = MMKVUtils.getString("service_phone_list")
|
||||
if (!TextUtils.isEmpty(str)) {
|
||||
return Gson().fromJson(str, object : TypeToken<List<String>>() {}.type)
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存个推cid
|
||||
*/
|
||||
fun saveGTCid(cid: String) {
|
||||
MMKVUtils.put("gt_cid", cid)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取个推cid
|
||||
*/
|
||||
fun getGTCid(): String {
|
||||
return MMKVUtils.getString("gt_cid") ?: ""
|
||||
}
|
||||
|
||||
private fun getOaId(callback: ((String) -> Unit)? = null) {
|
||||
val oaid = DeviceIdentifier.getOAID(Utils.getApp())
|
||||
if (TextUtils.isEmpty(oaid)) {
|
||||
DeviceID.getOAID(Utils.getApp(), object : IGetter {
|
||||
override fun onOAIDGetComplete(result: String) {
|
||||
MMKVUtils.put("oaid", result)
|
||||
callback?.invoke(result)
|
||||
}
|
||||
|
||||
override fun onOAIDGetError(error: Exception) {
|
||||
callback?.invoke("")
|
||||
}
|
||||
})
|
||||
} else {
|
||||
MMKVUtils.put("oaid", oaid)
|
||||
callback?.invoke(oaid)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存百度归因bd_vid
|
||||
*/
|
||||
fun saveBDVID() {
|
||||
try {
|
||||
val str = com.cheng.bole.utils.appwalle.ChannelReader.get(Utils.getApp())
|
||||
if (!TextUtils.isEmpty(str)) {
|
||||
val jsonObj = JSONObject(str)
|
||||
jsonObj.getString("bd_vid").let {
|
||||
MMKVUtils.put("bd_vid", it)
|
||||
}
|
||||
} else {
|
||||
MMKVUtils.put("bd_vid", "")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取百度归因bd_vid
|
||||
*/
|
||||
fun getBDVID(): String {
|
||||
return MMKVUtils.getString("bd_vid") ?: ""
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.cheng.bole.net
|
||||
|
||||
|
||||
object ApiFactory {
|
||||
val apiService: ApiService by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||
HttpRetrofit().apiService
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
package com.cheng.bole.net
|
||||
|
||||
import com.cheng.bole.net.model.HttpBaseResult
|
||||
import com.cheng.bole.net.model.HttpListResult
|
||||
import com.ylqh.cube.bean.CouponActivityEntity
|
||||
import okhttp3.MultipartBody
|
||||
import okhttp3.RequestBody
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.DELETE
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Multipart
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.PUT
|
||||
import retrofit2.http.Part
|
||||
import retrofit2.http.Query
|
||||
import retrofit2.http.QueryMap
|
||||
|
||||
interface ApiService {
|
||||
|
||||
/**
|
||||
* 获取客户端配置
|
||||
*/
|
||||
@GET("/api/user/config")
|
||||
suspend fun getUserConfig(
|
||||
@Query("oaid") oaid: String,
|
||||
@Query("os_version") osVersion: Int,
|
||||
@Query("ua") ua: String,
|
||||
@Query("imei") imei: String,
|
||||
@Query("cid") cid: String,
|
||||
): HttpBaseResult<com.cheng.bole.bean.UserConfigEntity>
|
||||
|
||||
/**
|
||||
* 发送验证码
|
||||
*/
|
||||
@POST("/api/user/code")
|
||||
suspend fun sendCode(@Body params: Map<String, String>): HttpBaseResult<com.cheng.bole.bean.SendCodeEntity>
|
||||
|
||||
/**
|
||||
* 登录
|
||||
*/
|
||||
@POST("/api/user/login")
|
||||
suspend fun login(@Body requestBody: RequestBody): HttpBaseResult<com.cheng.bole.bean.LoginEntity>
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
@POST("/api/user/logout")
|
||||
suspend fun logout(): HttpBaseResult<Any>
|
||||
|
||||
/**
|
||||
*更新用户信息
|
||||
*/
|
||||
@PUT("/api/user")
|
||||
suspend fun changUser(@Body requestBody: RequestBody): HttpBaseResult<Any>
|
||||
|
||||
/**
|
||||
* 注销
|
||||
*/
|
||||
@POST("/api/user/destroy")
|
||||
suspend fun userDestroy(): HttpBaseResult<Any>
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*/
|
||||
@GET("/api/user")
|
||||
suspend fun userInfo(): HttpBaseResult<com.cheng.bole.bean.UserEntity>
|
||||
|
||||
/**
|
||||
* 获取账号列表
|
||||
*/
|
||||
@GET("/api/user/account")
|
||||
suspend fun accountList(@Query("scene") scene: String): HttpBaseResult<List<com.cheng.bole.bean.AccountEntity>>
|
||||
|
||||
/**
|
||||
* 上传图片
|
||||
*/
|
||||
@Multipart
|
||||
@POST("/api/user/upload")
|
||||
suspend fun upload(@Part part: MultipartBody.Part, @Query("scene") scene: String): HttpBaseResult<com.cheng.bole.bean.UploadImgEntity>
|
||||
|
||||
/**
|
||||
*删除用户文件
|
||||
*/
|
||||
@DELETE("/api/user/upload")
|
||||
suspend fun delUserFile(@Query("id") id: String): HttpBaseResult<Any>
|
||||
|
||||
/**
|
||||
* 联系客服
|
||||
*/
|
||||
@GET("/api/weixin/service")
|
||||
suspend fun wxService(): HttpBaseResult<com.cheng.bole.bean.WxServiceEntity>
|
||||
|
||||
/**
|
||||
* 事件上报
|
||||
*/
|
||||
@POST("/api/user/event")
|
||||
suspend fun eventReport(@Body requestBody: RequestBody): HttpBaseResult<Any>
|
||||
|
||||
/**
|
||||
* 推送回执接口
|
||||
*/
|
||||
@PUT("/api/push/receipt")
|
||||
suspend fun reportPushReceipt(@Body requestBody: RequestBody): HttpBaseResult<Any>
|
||||
|
||||
/**
|
||||
* 意见反馈
|
||||
*/
|
||||
@POST("/api/user/feedback")
|
||||
suspend fun feedback(@Body requestBody: RequestBody): HttpBaseResult<Any>
|
||||
|
||||
/**
|
||||
* 用户公告
|
||||
*/
|
||||
@GET("/api/user/notice")
|
||||
suspend fun notice(): HttpBaseResult<com.cheng.bole.bean.NoticeEntity>
|
||||
|
||||
/**
|
||||
* 获取VIP套餐列表
|
||||
*/
|
||||
@GET("/api/order/goods")
|
||||
suspend fun getGoodsList(@Query("type") type: String = "member"): HttpBaseResult<List<com.cheng.bole.bean.VipGoodsEntity>>
|
||||
|
||||
/**
|
||||
* 优惠券列表
|
||||
*/
|
||||
@GET("/api/activity/coupon")
|
||||
suspend fun couponList(@QueryMap params: Map<String, String>): HttpBaseResult<HttpListResult<com.cheng.bole.bean.CouponEntity>>
|
||||
|
||||
/**
|
||||
* 获取优惠活动列表
|
||||
*/
|
||||
@GET("/api/activity")
|
||||
suspend fun couponActivityList(@Query("scene") scene: String): HttpBaseResult<List<CouponActivityEntity>>
|
||||
|
||||
/**
|
||||
* 领取活动优惠券
|
||||
*/
|
||||
@POST("/api/activity")
|
||||
suspend fun getActivityCoupons(@Query("activity_id") ids: String): HttpBaseResult<Any>
|
||||
|
||||
/**
|
||||
* 创建支付订单
|
||||
*/
|
||||
@POST("/api/order")
|
||||
suspend fun payCreateOrder(@Body requestBody: RequestBody): HttpBaseResult<com.cheng.bole.bean.OrderPayEntity>
|
||||
|
||||
/**
|
||||
* 权限验证
|
||||
*/
|
||||
@GET("/api/user/auth")
|
||||
suspend fun checkPermission(@Query("scene") info: String?): HttpBaseResult<com.cheng.bole.bean.VipPermissionEntity>
|
||||
|
||||
/**
|
||||
* 权限上报
|
||||
*/
|
||||
@POST("/api/user/auth")
|
||||
suspend fun sendCheckPermission(@Body requestBody: RequestBody): HttpBaseResult<Any>
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.cheng.bole.net
|
||||
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import java.util.Locale
|
||||
|
||||
class ContentTypeInterceptor : Interceptor {
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val originalRequest = chain.request()
|
||||
val url = String.format("%s", originalRequest.url)
|
||||
val method = originalRequest.method.lowercase(Locale.getDefault()).trim { it <= ' ' }
|
||||
|
||||
if (!url.contains("user/upload")) {
|
||||
if(method == "post" || method == "put"){
|
||||
val newRequest = originalRequest.newBuilder()
|
||||
.header("Content-Type", "application/json; charset=utf-8")
|
||||
.method(originalRequest.method, originalRequest.body)
|
||||
.build()
|
||||
return chain.proceed(newRequest)
|
||||
}
|
||||
}
|
||||
return chain.proceed(originalRequest)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package com.cheng.bole.net
|
||||
|
||||
import com.cheng.bole.BuildConfig
|
||||
import com.cheng.bole.common.Constants
|
||||
import com.google.gson.GsonBuilder
|
||||
import okhttp3.OkHttpClient
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
/**
|
||||
* 网络请求方法 结合了rxJava
|
||||
*/
|
||||
class HttpRetrofit internal constructor() {
|
||||
companion object {
|
||||
private const val DEFAULT_TIMEOUT = 20L
|
||||
}
|
||||
|
||||
val apiService: ApiService
|
||||
|
||||
init {
|
||||
//手动创建一个OkHttpClient并设置超时时间
|
||||
val httpClient = OkHttpClient.Builder()
|
||||
httpClient.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
|
||||
//header拦截
|
||||
httpClient.addInterceptor(RequestHeaderInterceptor())
|
||||
httpClient.addInterceptor(ContentTypeInterceptor())
|
||||
//请求拦截
|
||||
httpClient.addInterceptor(RequestInterceptor())
|
||||
//响应拦截
|
||||
httpClient.addInterceptor(ResponseInterceptor())
|
||||
|
||||
|
||||
val gson = GsonBuilder().setLenient().registerTypeAdapterFactory(MyTypeAdapterFactory()).create()
|
||||
val retrofit = Retrofit.Builder()
|
||||
.client(httpClient.build())
|
||||
.addConverterFactory(GsonConverterFactory.create(gson))
|
||||
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
|
||||
.baseUrl(if (BuildConfig.DEBUG) Constants.TestUrl else Constants.BaseUrl)
|
||||
.build()
|
||||
|
||||
apiService = retrofit.create(ApiService::class.java)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
package com.cheng.bole.net
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.TypeAdapter
|
||||
import com.google.gson.TypeAdapterFactory
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.google.gson.stream.JsonReader
|
||||
import com.google.gson.stream.JsonToken
|
||||
import com.google.gson.stream.JsonWriter
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* @date 2020-06-05 13:53
|
||||
* @desc gson数据类型转换处理
|
||||
*/
|
||||
class MyTypeAdapterFactory : TypeAdapterFactory {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? {
|
||||
//type.rawType 这个类型是实体的类型 不是服务器返回的数据类型
|
||||
return when (type.rawType) {
|
||||
String::class.java -> StringNullAdapter() as TypeAdapter<T>
|
||||
Int::class.java -> IntNullAdapter() as TypeAdapter<T>
|
||||
Long::class.java -> LongNullAdapter() as TypeAdapter<T>
|
||||
Double::class.java -> DoubleNullAdapter() as TypeAdapter<T>
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
//字符串处理
|
||||
class StringNullAdapter : TypeAdapter<String>() {
|
||||
@Throws(IOException::class)
|
||||
override fun read(reader: JsonReader): String {
|
||||
if (reader.peek() == JsonToken.NULL) {
|
||||
reader.nextNull()
|
||||
return ""
|
||||
}
|
||||
return reader.nextString()
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun write(writer: JsonWriter, value: String?) {
|
||||
if (value == null) {
|
||||
writer.nullValue()
|
||||
return
|
||||
}
|
||||
writer.value(value)
|
||||
}
|
||||
}
|
||||
|
||||
//Int处理
|
||||
inner class IntNullAdapter : TypeAdapter<Int>() {
|
||||
@Throws(IOException::class)
|
||||
override fun read(reader: JsonReader): Int {
|
||||
val jt = reader.peek()
|
||||
if (jt == JsonToken.NULL) {
|
||||
reader.nextNull()
|
||||
return 0
|
||||
}
|
||||
if (jt == JsonToken.STRING) {
|
||||
return reader.nextString().toIntOrNull() ?: 0
|
||||
}
|
||||
return reader.nextInt()
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun write(writer: JsonWriter, value: Int?) {
|
||||
if (value == null) {
|
||||
writer.nullValue()
|
||||
return
|
||||
}
|
||||
writer.value(value)
|
||||
}
|
||||
}
|
||||
|
||||
//Long处理
|
||||
inner class LongNullAdapter : TypeAdapter<Long>() {
|
||||
@Throws(IOException::class)
|
||||
override fun read(reader: JsonReader): Long {
|
||||
val jt = reader.peek()
|
||||
if (jt == JsonToken.NULL) {
|
||||
reader.nextNull()
|
||||
return 0
|
||||
}
|
||||
if (jt == JsonToken.STRING) {
|
||||
return reader.nextString().toLongOrNull() ?: 0L
|
||||
}
|
||||
return reader.nextLong()
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun write(writer: JsonWriter, value: Long?) {
|
||||
if (value == null) {
|
||||
writer.nullValue()
|
||||
return
|
||||
}
|
||||
writer.value(value)
|
||||
}
|
||||
}
|
||||
|
||||
//Double处理
|
||||
inner class DoubleNullAdapter : TypeAdapter<Double>() {
|
||||
@Throws(IOException::class)
|
||||
override fun read(reader: JsonReader): Double {
|
||||
val jt = reader.peek()
|
||||
if (jt == JsonToken.NULL) {
|
||||
reader.nextNull()
|
||||
return 0.0
|
||||
}
|
||||
if (jt == JsonToken.STRING) {
|
||||
return reader.nextString().toDoubleOrNull() ?: 0.0
|
||||
}
|
||||
return reader.nextDouble()
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun write(writer: JsonWriter, value: Double?) {
|
||||
if (value == null) {
|
||||
writer.nullValue()
|
||||
return
|
||||
}
|
||||
writer.value(value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package com.cheng.bole.net
|
||||
|
||||
import com.cheng.bole.BuildConfig
|
||||
import com.cheng.bole.manager.LoginManager
|
||||
import com.cheng.bole.utils.ChannelUtils
|
||||
import com.example.base.utils.AppUtils
|
||||
import com.example.base.utils.L
|
||||
import com.example.base.utils.Utils
|
||||
import com.github.gzuliyujiang.oaid.DeviceIdentifier
|
||||
import com.cheng.bole.common.Constants
|
||||
import com.cheng.bole.manager.UserConfigManager
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
|
||||
class RequestHeaderInterceptor : Interceptor {
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
var request = chain.request()
|
||||
val requestBuilder = request.newBuilder()
|
||||
|
||||
//添加header
|
||||
request = requestBuilder
|
||||
.addHeader("x-token", LoginManager.getToken())
|
||||
.addHeader("x-version", AppUtils.getAppVersionName())
|
||||
.addHeader("x-platform", "android")
|
||||
.addHeader("x-device-id", DeviceIdentifier.getAndroidID(Utils.getApp()))
|
||||
.addHeader("x-mobile-brand", android.os.Build.BRAND)
|
||||
.addHeader("x-mobile-model", android.os.Build.MODEL)
|
||||
.addHeader("x-base-version", AppUtils.getAppVersionName())
|
||||
.addHeader("x-channel", "jk_${ChannelUtils.getChannel()}")
|
||||
.addHeader("x-click-id", UserConfigManager.getBDVID())
|
||||
.addHeader("x-app-id", Constants.APP_ID)
|
||||
.addHeader("x-package", BuildConfig.APPLICATION_ID)
|
||||
.build()
|
||||
val stringBuilder = StringBuilder()
|
||||
stringBuilder.append("-------------header start-------------\n")
|
||||
stringBuilder.append("x-token = ${LoginManager.getToken()}\n")
|
||||
stringBuilder.append("x-version = ${AppUtils.getAppVersionName()}\n")
|
||||
stringBuilder.append("x-device-id = ${DeviceIdentifier.getAndroidID(Utils.getApp())}\n")
|
||||
stringBuilder.append("x-mobile-brand = ${android.os.Build.BRAND}\n")
|
||||
stringBuilder.append("x-mobile-model = ${android.os.Build.MODEL}\n")
|
||||
stringBuilder.append("x-base-version = ${AppUtils.getAppVersionName()}\n")
|
||||
stringBuilder.append("x-channel = jk_${ChannelUtils.getChannel()}\n")
|
||||
stringBuilder.append("x-click-id = ${UserConfigManager.getBDVID()}\n")
|
||||
stringBuilder.append("x-package = ${BuildConfig.APPLICATION_ID}\n")
|
||||
stringBuilder.append("-------------header end-------------")
|
||||
L.d(stringBuilder)
|
||||
|
||||
return chain.proceed(request)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package com.cheng.bole.net
|
||||
|
||||
import android.text.TextUtils
|
||||
import com.cheng.bole.common.Constants
|
||||
import com.cheng.bole.utils.StringUtils
|
||||
import com.example.base.utils.L
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import okio.Buffer
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.Arrays
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* @date 2020-06-05 13:53
|
||||
* @desc 网络请求可以在此处添加n多的请求拦截-加密数据
|
||||
*/
|
||||
|
||||
class RequestInterceptor : Interceptor {
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
var request = chain.request()
|
||||
val method = request.method.lowercase(Locale.getDefault()).trim { it <= ' ' }
|
||||
val url = request.url
|
||||
val apiPath = String.format("%s", url)
|
||||
L.d("TAG-->>url=$apiPath")
|
||||
//如果请求的不是服务端的接口则不用加密
|
||||
if (!apiPath.startsWith(Constants.BaseUrl)) {
|
||||
L.d("TAG-->>content-type=${request.headers["Content-Type"]}")
|
||||
val requestBody = request.body
|
||||
L.d("TAG-->>${requestBody.toString()}")
|
||||
return chain.proceed(request)
|
||||
}
|
||||
var queryString = url.encodedQuery
|
||||
queryString = if (!TextUtils.isEmpty(queryString)) {
|
||||
(queryString + "&nonce=" + StringUtils.createUUID()) + "×tamp=" + System.currentTimeMillis() / 1000
|
||||
} else {
|
||||
("nonce=" + StringUtils.createUUID()) + "×tamp=" + System.currentTimeMillis() / 1000
|
||||
}
|
||||
val sortQueryString = Arrays.stream(queryString.split("&".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray())
|
||||
.sorted { obj: String, anotherString: String? -> obj.compareTo(anotherString!!) }
|
||||
.reduce { x: String, y: String -> "$x&$y" }
|
||||
.get()
|
||||
//如果请求方式是get或者delete 则没有body
|
||||
var paramsStr = ""
|
||||
var bytes = ByteArray(0)
|
||||
var signature: String? = ""
|
||||
if (method == "put" || method == "post") {
|
||||
val requestBody = request.body
|
||||
L.d("TAG-->>${requestBody.toString()}")
|
||||
val buffer = Buffer()
|
||||
requestBody!!.writeTo(buffer)
|
||||
bytes = StringUtils.addByte(bytes, buffer.readByteArray())
|
||||
L.e("签名后bodyByte的长度为" + bytes.size)
|
||||
paramsStr = String(bytes, StandardCharsets.UTF_8)
|
||||
// paramsStr = buffer.readUtf8();
|
||||
L.e("签名后body的长度为" + paramsStr.length)
|
||||
}
|
||||
signature = if (bytes.isNotEmpty()) {
|
||||
L.e("当前的数组长度为----" + bytes.size)
|
||||
StringUtils.getMD5Byte(
|
||||
StringUtils.addByte(
|
||||
StringUtils.addByte("$sortQueryString&".toByteArray(), bytes),
|
||||
("&" + StringUtils.getMD5String(Constants.Signature)).toByteArray()
|
||||
)
|
||||
)
|
||||
} else {
|
||||
StringUtils.getMD5String(sortQueryString + "&" + StringUtils.getMD5String(Constants.Signature))
|
||||
}
|
||||
val newUrl = apiPath.split("\\?".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0] + "?" + queryString + "&signature=" + signature
|
||||
L.e("签名后的路径---", newUrl)
|
||||
request = request.newBuilder().url(newUrl).build()
|
||||
|
||||
return chain.proceed(request)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
package com.cheng.bole.net
|
||||
|
||||
import android.content.Intent
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import com.alibaba.fastjson.JSON
|
||||
import com.example.base.common.RxBus
|
||||
import com.example.base.utils.L
|
||||
import com.example.base.utils.Utils
|
||||
import com.cheng.bole.BuildConfig
|
||||
import com.cheng.bole.common.Constants
|
||||
import com.cheng.bole.manager.LoginManager
|
||||
import com.cheng.bole.ui.activity.LoginActivity
|
||||
import com.cheng.bole.ui.activity.PublicActivity
|
||||
import com.cheng.bole.ui.fragment.mine.vip.VipFragment
|
||||
import com.cheng.bole.utils.AESpkcs7paddingUtil
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.Response
|
||||
import okhttp3.ResponseBody
|
||||
import java.nio.charset.Charset
|
||||
import java.nio.charset.UnsupportedCharsetException
|
||||
|
||||
|
||||
/**
|
||||
* @date 2020-06-05 13:55
|
||||
* @desc 可以在此处添加n多的响应拦截- 比如解密数据
|
||||
*/
|
||||
class ResponseInterceptor : Interceptor {
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val request = chain.request()
|
||||
val url = request.url
|
||||
val apiPath = String.format("%s", url)
|
||||
//如果请求的不是服务端的接口则不用加密
|
||||
if (!apiPath.startsWith(if (BuildConfig.DEBUG) Constants.TestUrl else Constants.BaseUrl)) {
|
||||
return chain.proceed(request)
|
||||
}
|
||||
val response = chain.proceed(request)
|
||||
var charset = Charset.forName("UTF-8")
|
||||
val contentType = response.header("Content-Type")
|
||||
if (contentType != null && contentType.contains("application/json")) {
|
||||
val responseBody = response.body
|
||||
if (responseBody != null) {
|
||||
val source = responseBody.source()
|
||||
source.request(Long.MAX_VALUE)
|
||||
val buffer = source.buffer
|
||||
val mediaType = responseBody.contentType()
|
||||
if (mediaType != null) {
|
||||
try {
|
||||
charset = mediaType.charset(Charset.forName("UTF-8"))
|
||||
} catch (e: UnsupportedCharsetException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
val respBody = buffer.clone().readString(charset!!)
|
||||
L.d("response=${respBody}")
|
||||
if (TextUtils.isEmpty(respBody)) {
|
||||
return response
|
||||
}
|
||||
val code = JSON.parseObject(respBody).getInteger("code")
|
||||
if (code == 1001003 || code == 1001004 || code == 1001005) {
|
||||
LoginManager.logout()
|
||||
val intent = Intent(Utils.getApp(), LoginActivity::class.java)
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
Utils.getApp().startActivity(intent)
|
||||
}
|
||||
|
||||
val isEncrypt = JSON.parseObject(respBody).getBoolean("encrypt")
|
||||
L.e("是否需要解密$isEncrypt")
|
||||
if (isEncrypt == null || !isEncrypt) { //如果不需要加密 直接返回
|
||||
L.d("response=${response.body}")
|
||||
return response
|
||||
}
|
||||
val decrybody = JSON.parseObject(respBody).getString("data")
|
||||
L.e("Json解析后的字符串为$decrybody")
|
||||
var decryString: String?
|
||||
try {
|
||||
decryString = AESpkcs7paddingUtil.decryptNormal(decrybody, Constants.Encrypt)
|
||||
Log.e("ResponseInterceptor", "解密后返回的字符串为$decryString")
|
||||
val decCode = JSON.parseObject(decryString).getInteger("code")
|
||||
when (decCode) {
|
||||
11018 -> {
|
||||
RxBus.defaultInstance.post(com.cheng.bole.event.HomeRefreshEvent())
|
||||
}
|
||||
|
||||
19000 -> {
|
||||
PublicActivity.newStart(Utils.getApp(), VipFragment::class.java, Pair("origin", "interceptor"))
|
||||
}
|
||||
|
||||
1001003, 1001004, 1001005 -> {
|
||||
LoginManager.logout()
|
||||
val intent = Intent(Utils.getApp(), LoginActivity::class.java)
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
Utils.getApp().startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
//返回新创建的response
|
||||
return response.newBuilder().body(ResponseBody.create("text/plain".toMediaType(), decryString)).build()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.cheng.bole.net.model
|
||||
|
||||
/**
|
||||
* @date 2021-08-05 09:45
|
||||
* @desc 数据基本结构
|
||||
*/
|
||||
data class HttpBaseResult<T>(val code: Int, val data: T) {
|
||||
|
||||
val status: Boolean
|
||||
get() {
|
||||
return code == 0
|
||||
}
|
||||
val message: String = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* @param
|
||||
* 获取数据转成 Result<T>
|
||||
*/
|
||||
fun <T> HttpBaseResult<T>.toResult(): Result<T> {
|
||||
return if (this.status) {
|
||||
Result.success(this.data)
|
||||
} else {
|
||||
Result.failure(RuntimeException(this.message))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param
|
||||
* 获取数据转成 Result<List<T>>
|
||||
*/
|
||||
fun <T> HttpBaseResult<HttpListResult<T>>.toListResult(): Result<List<T>> {
|
||||
return if (this.status) {
|
||||
Result.success(this.data.items)
|
||||
} else {
|
||||
Result.failure(RuntimeException(this.message))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package com.cheng.bole.net.model
|
||||
|
||||
|
||||
/**
|
||||
* 列表基本结构(服务返回)
|
||||
*/
|
||||
|
||||
open class HttpListResult<T> {
|
||||
|
||||
var total: String = "0" //总条数
|
||||
var total_amount:String = "0.00" //总金额
|
||||
|
||||
private var content = listOf<T>() //列表数据
|
||||
private var records = listOf<T>() //列表数据
|
||||
private var list = listOf<T>() //列表数据
|
||||
val items = listOf<T>() //列表数据
|
||||
get() {
|
||||
if (content.isNotEmpty()) {
|
||||
return content
|
||||
}
|
||||
if (records.isNotEmpty()) {
|
||||
return records
|
||||
}
|
||||
if (list.isNotEmpty()) {
|
||||
return list
|
||||
}
|
||||
return field // 防止服务器数据为null 蛋疼
|
||||
}
|
||||
|
||||
|
||||
override fun toString(): String {
|
||||
return "HttpListResult{" +
|
||||
"total=" + total +
|
||||
"total_amount="+total_amount+
|
||||
", rows=" + items +
|
||||
'}'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
package com.cheng.bole.ui.activity
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentContainerView
|
||||
import com.example.base.extensions.onClick
|
||||
import com.example.base.ui.BaseActivity
|
||||
import com.example.base.utils.ScreenUtils
|
||||
import org.jetbrains.anko.find
|
||||
|
||||
|
||||
/**
|
||||
* 仿抽屉activity
|
||||
*/
|
||||
class DrawerActivity : BaseActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val containerView = find<FragmentContainerView>(com.example.base.R.id.fcvContainer)
|
||||
val lp = containerView.layoutParams as FrameLayout.LayoutParams
|
||||
lp.width = (ScreenUtils.getWindowSize().x * 0.75).toInt()
|
||||
lp.height = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
lp.gravity = Gravity.END
|
||||
containerView.layoutParams = lp
|
||||
|
||||
window.decorView.find<View>(android.R.id.content).onClick { finish() }
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
window.setBackgroundDrawable(ColorDrawable(Color.parseColor("#80000000")))
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun getFragment(): Fragment {
|
||||
val className = intent.getStringExtra(FRAGMENT_CLASS_NAME)!!
|
||||
val clazz = Class.forName(className)
|
||||
|
||||
val fragment = clazz.getDeclaredConstructor().newInstance() as Fragment
|
||||
fragment.arguments = intent.extras
|
||||
return fragment
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val FRAGMENT_CLASS_NAME = "fragment_class_name"
|
||||
|
||||
fun start(context: Context?, clazz: Class<out Fragment>, vararg args: Pair<String, *>) {
|
||||
val intent = Intent(context, DrawerActivity::class.java)
|
||||
intent.putExtra(FRAGMENT_CLASS_NAME, clazz.name)
|
||||
intent.putExtras(bundleOf(*args))
|
||||
|
||||
context?.startActivity(intent)
|
||||
}
|
||||
|
||||
fun newStart(context: Context?, clazz: Class<out Fragment>, vararg args: Pair<String, *>) {
|
||||
val intent = Intent(context, DrawerActivity::class.java)
|
||||
intent.putExtra(FRAGMENT_CLASS_NAME, clazz.name)
|
||||
intent.putExtras(bundleOf(*args))
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
context?.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package com.cheng.bole.ui.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.window.OnBackInvokedDispatcher
|
||||
import androidx.activity.addCallback
|
||||
import androidx.core.os.BuildCompat
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.ui.fragment.guide.GuideFragment
|
||||
import com.example.base.common.ActivityManager
|
||||
import com.example.base.extensions.toast
|
||||
import com.example.base.ui.BaseActivity
|
||||
|
||||
class GuideActivity :BaseActivity(){
|
||||
|
||||
private var lastBackClickTime = 0L
|
||||
override fun getFragment() = GuideFragment()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
backApp()
|
||||
}
|
||||
|
||||
@SuppressLint("UnsafeOptInUsageError")
|
||||
private fun backApp() {
|
||||
if (BuildCompat.isAtLeastT()) {
|
||||
onBackInvokedDispatcher.registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT) {
|
||||
exitApp()
|
||||
}
|
||||
} else {
|
||||
onBackPressedDispatcher.addCallback(this) {
|
||||
exitApp()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun exitApp() {
|
||||
if (System.currentTimeMillis() - lastBackClickTime > 1500) {
|
||||
toast(getString(R.string.exit_app))
|
||||
lastBackClickTime = System.currentTimeMillis()
|
||||
} else {
|
||||
ActivityManager.exitApp()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
package com.cheng.bole.ui.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.window.OnBackInvokedDispatcher
|
||||
import androidx.activity.addCallback
|
||||
import androidx.core.os.BuildCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.bytedance.ads.convert.BDConvert
|
||||
import com.cheng.bole.BuildConfig
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.common.Constants
|
||||
import com.cheng.bole.common.EventConstants
|
||||
import com.cheng.bole.manager.DialogEnum
|
||||
import com.cheng.bole.manager.EventReportManager
|
||||
import com.cheng.bole.manager.LoginManager
|
||||
import com.cheng.bole.manager.UserConfigManager
|
||||
import com.cheng.bole.ui.dialog.PrivacyPolicyDialog
|
||||
import com.cheng.bole.utils.ChannelUtils
|
||||
import com.example.base.dialog.LoadingDialog
|
||||
import com.example.base.ui.BaseActivity
|
||||
import com.example.base.utils.L
|
||||
import com.example.base.utils.MMKVUtils
|
||||
import com.example.base.utils.Utils
|
||||
import com.g.gysdk.GYManager
|
||||
import com.g.gysdk.GYResponse
|
||||
import com.g.gysdk.GyCallBack
|
||||
import com.g.gysdk.GyConfig
|
||||
import com.gyf.immersionbar.BarHide
|
||||
import com.gyf.immersionbar.ImmersionBar
|
||||
import com.umeng.analytics.MobclickAgent
|
||||
import com.umeng.commonsdk.UMConfigure
|
||||
import org.jetbrains.anko.startActivity
|
||||
|
||||
|
||||
/**
|
||||
* 闪屏页
|
||||
*/
|
||||
class LauncherActivity : BaseActivity() {
|
||||
|
||||
private val privacyPolicyDialog by lazy {
|
||||
PrivacyPolicyDialog()
|
||||
}
|
||||
|
||||
private val loadingDialog by lazy {
|
||||
LoadingDialog(this)
|
||||
}
|
||||
|
||||
override fun getFragment() = Fragment(R.layout.activity_launcher)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
ImmersionBar.with(this).hideBar(BarHide.FLAG_HIDE_NAVIGATION_BAR).init()
|
||||
backApp()
|
||||
|
||||
if (MMKVUtils.getBoolean("isAgree")) {
|
||||
loadingDialog.show()
|
||||
UserConfigManager.saveBDVID()
|
||||
UserConfigManager.getUserConfig {
|
||||
EventReportManager.eventReport(EventConstants.APP_LAUNCH, "", "")
|
||||
loadingDialog.dismiss()
|
||||
initUM()
|
||||
initBD()
|
||||
initGT()
|
||||
intentMain()
|
||||
}
|
||||
} else {
|
||||
privacyDialog()
|
||||
}
|
||||
}
|
||||
|
||||
private fun privacyDialog() {
|
||||
privacyPolicyDialog.setOnSelectListener {
|
||||
if (it == DialogEnum.CLICK_OK) {
|
||||
loadingDialog.show()
|
||||
MMKVUtils.put("isAgree", true)
|
||||
UserConfigManager.saveBDVID()
|
||||
UserConfigManager.getUserConfig {
|
||||
EventReportManager.eventReport(EventConstants.APP_LAUNCH, "", "")
|
||||
loadingDialog.dismiss()
|
||||
initUM()
|
||||
initBD()
|
||||
initGT()
|
||||
intentMain()
|
||||
}
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
privacyPolicyDialog.show(supportFragmentManager, null)
|
||||
}
|
||||
|
||||
private fun intentMain() {
|
||||
if (UserConfigManager.isFirstUseApp()) {
|
||||
UserConfigManager.saveFirstUseApp(false)
|
||||
if (UserConfigManager.getGuideEnable()) {
|
||||
startActivity<GuideActivity>()
|
||||
} else {
|
||||
if (!LoginManager.isLogin()) {
|
||||
if (TextUtils.isEmpty(LoginManager.getLastLoginType())) {
|
||||
startActivity<MainActivity>()
|
||||
} else {
|
||||
LoginActivity.start(this@LauncherActivity)
|
||||
}
|
||||
} else {
|
||||
startActivity<MainActivity>()
|
||||
}
|
||||
}
|
||||
finish()
|
||||
} else {
|
||||
if (!LoginManager.isLogin()) {
|
||||
if (TextUtils.isEmpty(LoginManager.getLastLoginType())) {
|
||||
startActivity<MainActivity>()
|
||||
} else {
|
||||
LoginActivity.start(this@LauncherActivity)
|
||||
}
|
||||
} else {
|
||||
startActivity<MainActivity>()
|
||||
}
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化友盟
|
||||
*/
|
||||
private fun initUM() {
|
||||
UMConfigure.preInit(Utils.getApp(), Constants.UmengAppkey, ChannelUtils.getChannel())
|
||||
UMConfigure.init(this, Constants.UmengAppkey, ChannelUtils.getChannel(), UMConfigure.DEVICE_TYPE_PHONE, "")
|
||||
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO)
|
||||
}
|
||||
|
||||
/**
|
||||
* 巨量融合初始化
|
||||
*/
|
||||
private fun initBD() {
|
||||
BDConvert.init(Utils.getApp(), this)
|
||||
}
|
||||
|
||||
/**
|
||||
* 个推初始化
|
||||
*/
|
||||
private fun initGT() {
|
||||
GYManager.getInstance().preInit(this) //个验SDK初始化
|
||||
GYManager.getInstance().init(
|
||||
GyConfig.with(this)
|
||||
.preLoginUseCache(true)//预取号使用缓存,可以提高预取号的成功率,建议设置为true
|
||||
.channel(ChannelUtils.getChannel())//应用渠道
|
||||
.eLoginDebug(BuildConfig.DEBUG)//运营商debug调试模式
|
||||
.debug(BuildConfig.DEBUG)//个验debug调试模式
|
||||
.callBack(object : GyCallBack {
|
||||
override fun onSuccess(gyResponse: GYResponse) {
|
||||
L.d("TAG-->>GYManager init onSuccess =${gyResponse.code}")
|
||||
}
|
||||
|
||||
override fun onFailed(gyResponse: GYResponse) {
|
||||
L.d("TAG-->>GYManager init onFailed =${gyResponse.code}")
|
||||
}
|
||||
}).build()
|
||||
)
|
||||
//预登录
|
||||
GYManager.getInstance().ePreLogin(8000, object : GyCallBack {
|
||||
override fun onSuccess(gyResponse: GYResponse) {
|
||||
L.d("TAG-->>GYManager ePreLogin onSuccess =${gyResponse.code}")
|
||||
}
|
||||
|
||||
override fun onFailed(gyResponse: GYResponse) {
|
||||
L.d("TAG-->>GYManager ePreLogin onFailed =${gyResponse.code}")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@SuppressLint("UnsafeOptInUsageError")
|
||||
private fun backApp() {
|
||||
if (BuildCompat.isAtLeastT()) {
|
||||
onBackInvokedDispatcher.registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT) {
|
||||
}
|
||||
} else {
|
||||
onBackPressedDispatcher.addCallback(this) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package com.cheng.bole.ui.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.window.OnBackInvokedDispatcher
|
||||
import androidx.activity.addCallback
|
||||
import androidx.core.os.BuildCompat
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.common.EventConstants
|
||||
import com.cheng.bole.manager.EventReportManager
|
||||
import com.cheng.bole.ui.fragment.login.LoginFragment
|
||||
import com.cheng.bole.ui.fragment.login.onekey.OneKeyLoginFragment
|
||||
import com.example.base.common.ActivityManager
|
||||
import com.example.base.extensions.toast
|
||||
import com.example.base.ui.BaseActivity
|
||||
import com.g.gysdk.GYManager
|
||||
|
||||
class LoginActivity : BaseActivity() {
|
||||
|
||||
private var lastBackClickTime = 0L
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val from = intent.getIntExtra("from", 0)
|
||||
if (from == 0) backApp()
|
||||
}
|
||||
|
||||
override fun getFragment(): Fragment {
|
||||
val fragment = if (GYManager.getInstance().isPreLoginResultValid) {
|
||||
OneKeyLoginFragment()
|
||||
} else {
|
||||
LoginFragment()
|
||||
}
|
||||
fragment.arguments = intent.extras
|
||||
return fragment
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun start(activity: Activity?, vararg args: Pair<String, *>) {
|
||||
val intent = Intent(activity, LoginActivity::class.java)
|
||||
intent.putExtras(bundleOf(*args))
|
||||
activity?.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("UnsafeOptInUsageError")
|
||||
private fun backApp() {
|
||||
if (BuildCompat.isAtLeastT()) {
|
||||
onBackInvokedDispatcher.registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT) {
|
||||
exitApp()
|
||||
}
|
||||
} else {
|
||||
onBackPressedDispatcher.addCallback(this) {
|
||||
exitApp()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun exitApp() {
|
||||
if (System.currentTimeMillis() - lastBackClickTime > 1500) {
|
||||
toast(getString(R.string.exit_app))
|
||||
lastBackClickTime = System.currentTimeMillis()
|
||||
} else {
|
||||
EventReportManager.eventReport(EventConstants.EXIT_APP, "login", "")
|
||||
ActivityManager.exitApp()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
package com.cheng.bole.ui.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.window.OnBackInvokedDispatcher
|
||||
import androidx.activity.addCallback
|
||||
import androidx.core.os.BuildCompat
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.common.EventConstants
|
||||
import com.cheng.bole.event.LogoutSuccessEvent
|
||||
import com.cheng.bole.event.PushMessageEvent
|
||||
import com.cheng.bole.manager.EventReportManager
|
||||
import com.cheng.bole.ui.fragment.main.MainFragment
|
||||
import com.example.base.common.ActivityManager
|
||||
import com.example.base.common.RxBus
|
||||
import com.example.base.extensions.toast
|
||||
import com.example.base.ui.BaseActivity
|
||||
import com.example.base.utils.ClipboardUtils
|
||||
|
||||
class MainActivity : BaseActivity() {
|
||||
|
||||
private var lastBackClickTime = 0L
|
||||
|
||||
override fun getFragment() = MainFragment()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
backApp()
|
||||
|
||||
RxBus.defaultInstance.toObservable(LogoutSuccessEvent::class.java).subscribe { finish() }
|
||||
|
||||
handleIntent(intent)
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
handleIntent(intent)
|
||||
}
|
||||
|
||||
private fun handleIntent(intent: Intent?) {
|
||||
val payload = intent?.getStringExtra("payload")
|
||||
if (!TextUtils.isEmpty(payload)) {
|
||||
RxBus.defaultInstance.post(PushMessageEvent(payload!!, 3))
|
||||
} else {
|
||||
if (intent?.action == Intent.ACTION_SEND && intent.type == "text/plain") {
|
||||
val text = intent.getStringExtra(Intent.EXTRA_TEXT)
|
||||
ClipboardUtils.copyText(text)
|
||||
toast("复制成功")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("UnsafeOptInUsageError")
|
||||
private fun backApp() {
|
||||
if (BuildCompat.isAtLeastT()) {
|
||||
onBackInvokedDispatcher.registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT) {
|
||||
exitApp()
|
||||
}
|
||||
} else {
|
||||
onBackPressedDispatcher.addCallback(this) {
|
||||
exitApp()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun exitApp() {
|
||||
if (System.currentTimeMillis() - lastBackClickTime > 1500) {
|
||||
toast(getString(R.string.exit_app))
|
||||
lastBackClickTime = System.currentTimeMillis()
|
||||
} else {
|
||||
EventReportManager.eventReport(EventConstants.EXIT_APP, "main", "")
|
||||
ActivityManager.exitApp()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package com.cheng.bole.ui.activity
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.example.base.ui.BaseActivity
|
||||
|
||||
|
||||
/**
|
||||
* 所有的普通的fragment页面启动都用此activity装载
|
||||
*/
|
||||
class PublicActivity : BaseActivity() {
|
||||
private var mFragment: Fragment? = null
|
||||
|
||||
val attachedFragment: Fragment?
|
||||
get() = mFragment
|
||||
|
||||
override fun getFragment(): Fragment {
|
||||
val className = intent.getStringExtra(FRAGMENT_CLASS_NAME)!!
|
||||
val clazz = Class.forName(className)
|
||||
|
||||
mFragment = clazz.getDeclaredConstructor().newInstance() as Fragment
|
||||
mFragment!!.arguments = intent.extras
|
||||
return mFragment!!
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val FRAGMENT_CLASS_NAME = "fragment_class_name"
|
||||
|
||||
fun start(context: Context?, clazz: Class<out Fragment>, vararg args: Pair<String, *>) {
|
||||
val intent = Intent(context, PublicActivity::class.java)
|
||||
intent.putExtra(FRAGMENT_CLASS_NAME, clazz.name)
|
||||
intent.putExtras(bundleOf(*args))
|
||||
|
||||
context?.startActivity(intent)
|
||||
}
|
||||
|
||||
fun newStart(context: Context?, clazz: Class<out Fragment>, vararg args: Pair<String, *>) {
|
||||
val intent = Intent(context, PublicActivity::class.java)
|
||||
intent.putExtra(FRAGMENT_CLASS_NAME, clazz.name)
|
||||
intent.putExtras(bundleOf(*args))
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
context?.startActivity(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.cheng.bole.ui.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import com.cheng.bole.ui.fragment.video.VideoPlayerFragment
|
||||
import com.example.base.ui.BaseActivity
|
||||
|
||||
class VideoPlayerActivity : BaseActivity() {
|
||||
private var fragment: VideoPlayerFragment? = null
|
||||
|
||||
override fun getFragment() = fragment!!
|
||||
|
||||
@SuppressLint("SourceLockedOrientationActivity")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
val title = intent.getStringExtra("title") ?: ""
|
||||
val url = intent.getStringExtra("url") ?: ""
|
||||
fragment = VideoPlayerFragment.newInstance(url, title)
|
||||
fragment!!.setFullScreenChangedListener {
|
||||
// requestedOrientation = it
|
||||
}
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package com.cheng.bole.ui.base
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import com.cheng.bole.R
|
||||
|
||||
open class BaseDialog @JvmOverloads constructor(
|
||||
context: Context,
|
||||
styleRes: Int = R.style.BaseStyleDialog,
|
||||
private val isNoReturn: Boolean = false
|
||||
) : Dialog(context, styleRes) {
|
||||
|
||||
@SuppressLint("GestureBackNavigation")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
if (isNoReturn) {
|
||||
setOnKeyListener { _, keyCode, _ ->
|
||||
var isShield = false
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
isShield = true
|
||||
}
|
||||
isShield
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.cheng.bole.ui.base
|
||||
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter
|
||||
|
||||
class BasePageAdapter(
|
||||
private val fm: FragmentManager,
|
||||
private val titles: List<String>,
|
||||
private val mList: MutableList<Fragment>,
|
||||
behavior: Int = BEHAVIOR_SET_USER_VISIBLE_HINT
|
||||
) : FragmentStatePagerAdapter(fm, behavior) {
|
||||
|
||||
override fun getItem(position: Int): Fragment {
|
||||
return mList[position]
|
||||
}
|
||||
|
||||
override fun getCount(): Int {
|
||||
return mList.size
|
||||
}
|
||||
|
||||
override fun getPageTitle(position: Int): CharSequence? {
|
||||
if (titles.isEmpty()) return null
|
||||
return titles[position]
|
||||
}
|
||||
|
||||
override fun instantiateItem(container: View, position: Int): Any {
|
||||
val fragment = super.instantiateItem(container, position) as Fragment
|
||||
this.fm.beginTransaction().show(fragment).commit()
|
||||
return fragment
|
||||
}
|
||||
|
||||
override fun destroyItem(container: View, position: Int, `object`: Any) {
|
||||
val fragment = mList[position]
|
||||
fm.beginTransaction().hide(fragment).commitAllowingStateLoss()
|
||||
}
|
||||
|
||||
override fun getItemPosition(`object`: Any): Int {
|
||||
return POSITION_NONE
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
package com.cheng.bole.ui.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter
|
||||
import com.chad.library.adapter.base.viewholder.BaseViewHolder
|
||||
import com.example.base.decoration.SpacesItemDecoration
|
||||
import com.example.base.extensions.onClick
|
||||
import com.example.base.utils.DensityUtils
|
||||
import com.example.base.utils.ScreenUtils
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.common.Constants
|
||||
import com.cheng.bole.databinding.DialogAccountListBinding
|
||||
import com.cheng.bole.manager.DialogEnum
|
||||
|
||||
class AccountListDialog : DialogFragment() {
|
||||
private val btnText by lazy { arguments?.getString("btnText") ?: "我知道了" }
|
||||
private val mAdapter by lazy { AccountAdapter() }
|
||||
|
||||
private var mOnBackListener: ((DialogEnum) -> Unit)? = null //回调事件
|
||||
|
||||
lateinit var binding: DialogAccountListBinding
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val window = dialog?.window
|
||||
val windowParams = window?.attributes
|
||||
windowParams?.dimAmount = 0.7f
|
||||
windowParams?.width = (ScreenUtils.getWindowSize().x * 0.8).toInt()
|
||||
dialog?.window?.attributes = windowParams
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
dialog?.setCancelable(false)
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val view = layoutInflater.inflate(R.layout.dialog_account_list, null)
|
||||
|
||||
binding = DialogAccountListBinding.bind(view)
|
||||
|
||||
binding.tvTitle.typeface = Constants.youSheBiaoTiHei
|
||||
|
||||
binding.mRecyclerView.adapter = mAdapter
|
||||
binding.mRecyclerView.addItemDecoration(SpacesItemDecoration(DensityUtils.dp2px(10f)))
|
||||
|
||||
val listStr = arguments?.getString("list")
|
||||
if (!TextUtils.isEmpty(listStr)) {
|
||||
val list = Gson().fromJson<List<com.cheng.bole.bean.AccountEntity>>(listStr, object : TypeToken<List<com.cheng.bole.bean.AccountEntity>>(){}.type)
|
||||
mAdapter.setList(list)
|
||||
}
|
||||
|
||||
binding.tvOk.text = btnText
|
||||
|
||||
binding.tvOk.onClick {
|
||||
mOnBackListener?.invoke(DialogEnum.CLICK_OK)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
binding.ivClose.onClick { dismiss() }
|
||||
|
||||
val dialog = Dialog(requireContext())
|
||||
dialog.setContentView(view)
|
||||
return dialog
|
||||
}
|
||||
|
||||
fun setOnSelectListener(listener: ((DialogEnum) -> Unit)) {
|
||||
mOnBackListener = listener
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(list: List<com.cheng.bole.bean.AccountEntity>, btnText: String? = null): AccountListDialog {
|
||||
val arg = Bundle()
|
||||
arg.putString("list", Gson().toJson(list))
|
||||
arg.putString("btnText", btnText)
|
||||
val fragment = AccountListDialog()
|
||||
fragment.arguments = arg
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
|
||||
class AccountAdapter: BaseQuickAdapter<com.cheng.bole.bean.AccountEntity, BaseViewHolder>(R.layout.listitem_account_login_tip) {
|
||||
override fun convert(holder: BaseViewHolder, item: com.cheng.bole.bean.AccountEntity) {
|
||||
if (item.vip_type == "1") {
|
||||
holder.setGone(R.id.tv_vip_tag, true)
|
||||
} else if (item.vip_type == "2" || item.vip_type == "3") {
|
||||
holder.setText(R.id.tv_vip_tag, if (item.vip_type == "2") "会员" else "终生会员")
|
||||
holder.setGone(R.id.tv_vip_tag, false)
|
||||
}
|
||||
holder.setText(R.id.tv_username, item.name)
|
||||
holder.setText(R.id.tv_create_time, "${item.create_time} 注册")
|
||||
holder.setGone(R.id.iv_bind_wx, !item.bind.contains("weixin"))
|
||||
holder.setGone(R.id.iv_bind_phone, !item.bind.contains("phone"))
|
||||
if (!TextUtils.isEmpty(item.phone)) {
|
||||
holder.setText(R.id.tv_phone, item.phone.replaceRange(3, 7, "****"))
|
||||
} else {
|
||||
holder.setText(R.id.tv_phone, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
package com.cheng.bole.ui.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Dialog
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.example.base.common.RxCountDown
|
||||
import com.example.base.extensions.onClick
|
||||
import com.example.base.extensions.toast
|
||||
import com.example.base.utils.RegexUtils
|
||||
import com.example.base.utils.ScreenUtils
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.databinding.DialogBindPhoneBinding
|
||||
import com.cheng.bole.impl.TextWatcherImpl
|
||||
import com.cheng.bole.utils.KeyboardUtils
|
||||
import io.reactivex.rxjava3.disposables.Disposable
|
||||
|
||||
class BindPhoneDialog : DialogFragment(), KeyboardUtils.OnSoftInputChangedListener {
|
||||
private var mOnBackListener: ((String, String, String) -> Unit)? = null //回调事件
|
||||
private var mOnSendCodeClickListener:((String) -> Unit)? = null
|
||||
|
||||
private var disposable: Disposable? = null
|
||||
private var timestamp = ""
|
||||
|
||||
lateinit var binding: DialogBindPhoneBinding
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val window = dialog?.window
|
||||
val windowParams = window?.attributes
|
||||
windowParams?.dimAmount = 0.7f
|
||||
windowParams?.width = ScreenUtils.getWindowSize().x
|
||||
windowParams?.gravity = Gravity.BOTTOM
|
||||
windowParams?.windowAnimations = R.style.dialog_bottom
|
||||
dialog?.window?.attributes = windowParams
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
setCancelable(false)
|
||||
KeyboardUtils.registerSoftInputChangedListener(requireActivity(), this)
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
private val textWatcher = object : TextWatcherImpl() {
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
binding.ivClearText.visibility = if (TextUtils.isEmpty(s)) View.GONE else View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val view = layoutInflater.inflate(R.layout.dialog_bind_phone, null)
|
||||
|
||||
binding = DialogBindPhoneBinding.bind(view)
|
||||
|
||||
binding.etPhone.addTextChangedListener(textWatcher)
|
||||
|
||||
binding.ivClose.onClick {
|
||||
dismiss()
|
||||
}
|
||||
binding.ivClearText.onClick {
|
||||
binding.etPhone.setText("")
|
||||
}
|
||||
binding.tvSendCode.onClick {
|
||||
val phone = binding.etPhone.text?.trim().toString()
|
||||
if (TextUtils.isEmpty(phone)) {
|
||||
toast("请输入手机号")
|
||||
return@onClick
|
||||
}
|
||||
if (!RegexUtils.isMobileSimple(phone)) {
|
||||
toast("请输入正确的手机号")
|
||||
return@onClick
|
||||
}
|
||||
mOnSendCodeClickListener?.invoke(phone)
|
||||
}
|
||||
binding.btnNext.onClick {
|
||||
val phone = binding.etPhone.text?.trim().toString()
|
||||
val code = binding.etCode.text?.trim().toString()
|
||||
if (TextUtils.isEmpty(phone)) {
|
||||
toast("请输入手机号")
|
||||
return@onClick
|
||||
}
|
||||
if (!RegexUtils.isMobileSimple(phone)) {
|
||||
toast("请输入正确的手机号")
|
||||
return@onClick
|
||||
}
|
||||
if (TextUtils.isEmpty(code)) {
|
||||
toast("请输入验证码")
|
||||
return@onClick
|
||||
}
|
||||
mOnBackListener?.invoke(phone, code, timestamp)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
val dialog = Dialog(requireContext())
|
||||
dialog.setContentView(view)
|
||||
return dialog
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun startTimer() {
|
||||
disposable?.dispose()
|
||||
disposable = RxCountDown.countdown(60).subscribe {
|
||||
if (it > 0) {
|
||||
binding.tvSendCode.text = "${it}s"
|
||||
binding.tvSendCode.isEnabled = false
|
||||
binding.tvSendCode.alpha = 0.5f
|
||||
} else {
|
||||
binding.tvSendCode.text = "重新发送"
|
||||
binding.tvSendCode.isEnabled = true
|
||||
binding.tvSendCode.alpha = 1f
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setOnSendCodeClickListener(listener: (String) -> Unit) {
|
||||
mOnSendCodeClickListener = listener
|
||||
}
|
||||
|
||||
fun setOnBackListener(listener: (String, String, String) -> Unit) {
|
||||
mOnBackListener = listener
|
||||
}
|
||||
|
||||
fun setTimestamp(timestamp:String) {
|
||||
this.timestamp = timestamp
|
||||
startTimer()
|
||||
}
|
||||
|
||||
override fun onSoftInputChanged(height: Int) {
|
||||
val lp = binding.layoutContent.layoutParams as ConstraintLayout.LayoutParams
|
||||
lp.bottomMargin = height
|
||||
binding.layoutContent.layoutParams = lp
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
KeyboardUtils.unregisterSoftInputChangedListener(requireActivity().window)
|
||||
binding.etPhone.removeTextChangedListener(textWatcher)
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(): BindPhoneDialog {
|
||||
val arg = Bundle()
|
||||
val fragment = BindPhoneDialog()
|
||||
fragment.arguments = arg
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
package com.cheng.bole.ui.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Dialog
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import android.text.InputType
|
||||
import android.text.TextUtils
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.example.base.extensions.onClick
|
||||
import com.example.base.extensions.toast
|
||||
import com.example.base.utils.ScreenUtils
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.databinding.DialogEditTextBinding
|
||||
import com.cheng.bole.impl.TextWatcherImpl
|
||||
import com.cheng.bole.utils.KeyboardUtils
|
||||
|
||||
class EditTextDialog : DialogFragment(), KeyboardUtils.OnSoftInputChangedListener {
|
||||
private val title by lazy { arguments?.getString("title") ?: "" }
|
||||
private val content by lazy { arguments?.getString("content") ?: "" }
|
||||
private val hint by lazy { arguments?.getString("hint") }
|
||||
private val inputType by lazy { arguments?.getInt("input_type") ?: InputType.TYPE_CLASS_TEXT }
|
||||
private var mOnBackListener: ((String) -> Unit)? = null //回调事件
|
||||
|
||||
lateinit var binding: DialogEditTextBinding
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val window = dialog?.window
|
||||
val windowParams = window?.attributes
|
||||
windowParams?.dimAmount = 0.7f
|
||||
windowParams?.width = ScreenUtils.getWindowSize().x
|
||||
windowParams?.gravity = Gravity.BOTTOM
|
||||
windowParams?.windowAnimations = R.style.dialog_bottom
|
||||
dialog?.window?.attributes = windowParams
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
KeyboardUtils.registerSoftInputChangedListener(requireActivity(), this)
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
private val textWatcher = object : TextWatcherImpl() {
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
binding.ivClearText.visibility = if (TextUtils.isEmpty(s)) View.GONE else View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val view = layoutInflater.inflate(R.layout.dialog_edit_text, null)
|
||||
|
||||
binding = DialogEditTextBinding.bind(view)
|
||||
|
||||
binding.etContent.addTextChangedListener(textWatcher)
|
||||
|
||||
binding.tvTitle.text = title
|
||||
binding.etContent.hint = hint ?: "请输入"
|
||||
binding.etContent.setText(content)
|
||||
binding.etContent.inputType = inputType
|
||||
|
||||
binding.ivClose.onClick {
|
||||
dismiss()
|
||||
}
|
||||
binding.ivClearText.onClick {
|
||||
binding.etContent.setText("")
|
||||
}
|
||||
binding.btnNext.onClick {
|
||||
val content = binding.etContent.text?.trim().toString()
|
||||
if (TextUtils.isEmpty(content)) {
|
||||
toast(hint ?: "请输入内容")
|
||||
return@onClick
|
||||
}
|
||||
mOnBackListener?.invoke(content)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
val dialog = Dialog(requireContext())
|
||||
dialog.setContentView(view)
|
||||
return dialog
|
||||
}
|
||||
|
||||
fun setOnTextListener(listener: ((String) -> Unit)) {
|
||||
mOnBackListener = listener
|
||||
}
|
||||
|
||||
override fun onSoftInputChanged(height: Int) {
|
||||
val lp = binding.layoutContent.layoutParams as ConstraintLayout.LayoutParams
|
||||
lp.bottomMargin = height
|
||||
binding.layoutContent.layoutParams = lp
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
KeyboardUtils.unregisterSoftInputChangedListener(requireActivity().window)
|
||||
binding.etContent.removeTextChangedListener(textWatcher)
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(
|
||||
title: String? = null,
|
||||
content: String? = null,
|
||||
hint: String? = null,
|
||||
inputType: Int = InputType.TYPE_CLASS_TEXT
|
||||
): EditTextDialog {
|
||||
val arg = Bundle()
|
||||
val fragment = EditTextDialog()
|
||||
arg.putString("title", title)
|
||||
arg.putString("content", content)
|
||||
arg.putString("hint", hint)
|
||||
arg.putInt("input_type", inputType)
|
||||
fragment.arguments = arg
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
package com.cheng.bole.ui.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.example.base.browser.BrowserActivity
|
||||
import com.example.base.extensions.getColor
|
||||
import com.example.base.extensions.onClick
|
||||
import com.example.base.utils.ScreenUtils
|
||||
import com.example.base.utils.SpanUtils
|
||||
import com.g.gysdk.GYManager
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.common.Constants
|
||||
import com.cheng.bole.databinding.DialogLoginTipBinding
|
||||
import com.cheng.bole.utils.UrlHelper
|
||||
|
||||
class LoginTipDialog :DialogFragment(){
|
||||
private val type by lazy { arguments?.getInt("type") ?: 0 }
|
||||
|
||||
private var mOnBackListener: (() -> Unit)? = null //回调事件
|
||||
|
||||
lateinit var binding: DialogLoginTipBinding
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val window = dialog?.window
|
||||
val windowParams = window?.attributes
|
||||
windowParams?.dimAmount = 0.7f
|
||||
windowParams?.width = (ScreenUtils.getWindowSize().x * 0.8).toInt()
|
||||
dialog?.window?.attributes = windowParams
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val view = layoutInflater.inflate(R.layout.dialog_login_tip, null)
|
||||
|
||||
binding = DialogLoginTipBinding.bind(view)
|
||||
|
||||
binding.tvTitle.typeface = Constants.youSheBiaoTiHei
|
||||
|
||||
if (type == 0){
|
||||
initLoginPrivacyTv()
|
||||
} else {
|
||||
initOneKeyLoginPrivacyTv()
|
||||
}
|
||||
|
||||
binding.ivClose.onClick { dismiss() }
|
||||
binding.tvOk.onClick {
|
||||
mOnBackListener?.invoke()
|
||||
dismiss()
|
||||
}
|
||||
|
||||
val dialog = Dialog(requireContext())
|
||||
dialog.setContentView(view)
|
||||
return dialog
|
||||
}
|
||||
|
||||
fun setOnSelectListener(listener: (() -> Unit)) {
|
||||
mOnBackListener = listener
|
||||
}
|
||||
|
||||
private fun initLoginPrivacyTv() {
|
||||
SpanUtils.with(binding.tvTip)
|
||||
.append("登录之前须先查看并同意")
|
||||
.append("《用户协议》")
|
||||
.setClickSpan(getColor(R.color.color_466afd), false) {
|
||||
UrlHelper.startUserAgreement(requireContext())
|
||||
}
|
||||
.append("和")
|
||||
.append("《隐私政策》")
|
||||
.setClickSpan(getColor(R.color.color_466afd), false) {
|
||||
UrlHelper.startPrivacyPolicy(requireContext())
|
||||
}
|
||||
.create()
|
||||
}
|
||||
private fun initOneKeyLoginPrivacyTv() {
|
||||
val preLoginResult = GYManager.getInstance().preLoginResult
|
||||
SpanUtils.with(binding.tvTip)
|
||||
.append("登录之前须先查看并同意")
|
||||
.append("《${preLoginResult.privacyName}》")
|
||||
.setClickSpan(getColor(R.color.color_466afd), false) {
|
||||
BrowserActivity.start(requireContext(), preLoginResult.privacyName, preLoginResult.privacyUrl, false)
|
||||
}
|
||||
.append("、")
|
||||
.append("《用户协议》")
|
||||
.setClickSpan(getColor(R.color.color_466afd), false) {
|
||||
UrlHelper.startUserAgreement(requireContext())
|
||||
}
|
||||
.append("、")
|
||||
.append("《隐私政策》")
|
||||
.setClickSpan(getColor(R.color.color_466afd), false) {
|
||||
UrlHelper.startPrivacyPolicy(requireContext())
|
||||
}
|
||||
.create()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(type: Int = 0): LoginTipDialog {
|
||||
val arg = Bundle()
|
||||
val fragment = LoginTipDialog()
|
||||
arg.putInt("type", type)
|
||||
fragment.arguments = arg
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
package com.cheng.bole.ui.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.example.base.extensions.getColor
|
||||
import com.example.base.extensions.onClick
|
||||
import com.example.base.utils.ScreenUtils
|
||||
import com.example.base.utils.SpanUtils
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.common.Constants
|
||||
import com.cheng.bole.databinding.DialogPayTipBinding
|
||||
import com.cheng.bole.manager.DialogEnum
|
||||
import com.cheng.bole.utils.UrlHelper
|
||||
|
||||
class PayTipDialog : DialogFragment() {
|
||||
private val showRenew by lazy { arguments?.getBoolean("show_renew") ?: false }
|
||||
|
||||
private var mOnBackListener: ((DialogEnum) -> Unit)? = null //回调事件
|
||||
|
||||
lateinit var binding: DialogPayTipBinding
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val window = dialog?.window
|
||||
val windowParams = window?.attributes
|
||||
windowParams?.dimAmount = 0.7f
|
||||
windowParams?.width = (ScreenUtils.getWindowSize().x * 0.8).toInt()
|
||||
dialog?.window?.attributes = windowParams
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val view = layoutInflater.inflate(R.layout.dialog_pay_tip, null)
|
||||
|
||||
binding = DialogPayTipBinding.bind(view)
|
||||
|
||||
binding.tvTitle.typeface = Constants.youSheBiaoTiHei
|
||||
|
||||
binding.tvOk.onClick {
|
||||
mOnBackListener?.invoke(DialogEnum.CLICK_OK)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
binding.tvClose.onClick { dismiss() }
|
||||
binding.ivClose.onClick { dismiss() }
|
||||
|
||||
initAgreement()
|
||||
|
||||
val dialog = Dialog(requireContext())
|
||||
dialog.setContentView(view)
|
||||
return dialog
|
||||
}
|
||||
|
||||
private fun initAgreement() {
|
||||
val spanUtils = SpanUtils.with(binding.tvContent)
|
||||
.append("我已阅读并同意")
|
||||
.append("《会员服务协议规则》")
|
||||
.setClickSpan(getColor(R.color.color_466afd), false) {
|
||||
UrlHelper.startUserAgreement(requireContext(), "会员服务协议规则")
|
||||
}
|
||||
if (showRenew) {
|
||||
spanUtils.append("和")
|
||||
spanUtils.append("《自动续费服务规则》")
|
||||
spanUtils.setClickSpan(getColor(R.color.color_466afd), false) {
|
||||
UrlHelper.startRenewAgreement(requireContext())
|
||||
}
|
||||
}
|
||||
spanUtils.create()
|
||||
}
|
||||
|
||||
fun setOnSelectListener(listener: ((DialogEnum) -> Unit)) {
|
||||
mOnBackListener = listener
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(showRenew: Boolean = false): PayTipDialog {
|
||||
val arg = Bundle()
|
||||
arg.putBoolean("show_renew", showRenew)
|
||||
val fragment = PayTipDialog()
|
||||
fragment.arguments = arg
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package com.cheng.bole.ui.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.example.base.utils.ScreenUtils
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.databinding.DialogPermissionTipBinding
|
||||
|
||||
class PermissionTipDialog : DialogFragment() {
|
||||
|
||||
private var content: CharSequence? = null
|
||||
|
||||
lateinit var binding: DialogPermissionTipBinding
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val window = dialog?.window
|
||||
val windowParams = window?.attributes
|
||||
windowParams?.dimAmount = 0.7f
|
||||
windowParams?.width = (ScreenUtils.getWindowSize().x * 0.9).toInt()
|
||||
windowParams?.gravity = Gravity.TOP
|
||||
dialog?.window?.attributes = windowParams
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val view = layoutInflater.inflate(R.layout.dialog_permission_tip, null)
|
||||
|
||||
binding = DialogPermissionTipBinding.bind(view)
|
||||
|
||||
content = arguments?.getCharSequence("content")
|
||||
|
||||
if (!TextUtils.isEmpty(content)) {
|
||||
binding.tvContent.text = content
|
||||
}
|
||||
|
||||
val dialog = Dialog(requireContext())
|
||||
dialog.setContentView(view)
|
||||
return dialog
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(
|
||||
content: CharSequence,
|
||||
): PermissionTipDialog {
|
||||
val arg = Bundle()
|
||||
val fragment = PermissionTipDialog()
|
||||
arg.putCharSequence("content", content)
|
||||
fragment.arguments = arg
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.cheng.bole.ui.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.PopupWindow
|
||||
import com.example.base.extensions.onClick
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.databinding.PopAboutTipBinding
|
||||
import com.cheng.bole.ui.activity.PublicActivity
|
||||
import com.cheng.bole.ui.fragment.guide.GuideFragment
|
||||
import com.cheng.bole.ui.fragment.mine.about.AppConfigFragment
|
||||
|
||||
object PopupDialog {
|
||||
|
||||
fun showAboutTip(context: Context,v:View){
|
||||
val view = LayoutInflater.from(context).inflate(R.layout.pop_about_tip,null,false)
|
||||
val binding = PopAboutTipBinding.bind(view)
|
||||
|
||||
binding.tvTip1.onClick {
|
||||
PublicActivity.start(context, AppConfigFragment::class.java)
|
||||
}
|
||||
|
||||
binding.tvTip2.onClick {
|
||||
PublicActivity.start(context, GuideFragment::class.java)
|
||||
}
|
||||
|
||||
val popWindow = PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, true)
|
||||
popWindow.isClippingEnabled = false
|
||||
popWindow.isFocusable = true
|
||||
popWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
|
||||
val location = IntArray(2)
|
||||
v.getLocationOnScreen(location)
|
||||
val y: Int = location[1] + v.height
|
||||
val height = context.resources.displayMetrics.heightPixels - y
|
||||
popWindow.showAsDropDown(v, 0, 0)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
package com.cheng.bole.ui.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Dialog
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.example.base.extensions.getColor
|
||||
import com.example.base.extensions.onClick
|
||||
import com.example.base.utils.ScreenUtils
|
||||
import com.example.base.utils.SpanUtils
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.common.Constants
|
||||
import com.cheng.bole.databinding.DialogPrivacyPolicyBinding
|
||||
import com.cheng.bole.manager.DialogEnum
|
||||
import com.cheng.bole.utils.UrlHelper
|
||||
|
||||
class PrivacyPolicyDialog : DialogFragment() {
|
||||
|
||||
private var mOnBackListener: ((DialogEnum) -> Unit)? = null //回调事件
|
||||
|
||||
lateinit var binding: DialogPrivacyPolicyBinding
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val window = dialog?.window
|
||||
val windowParams = window?.attributes
|
||||
windowParams?.dimAmount = 0.7f
|
||||
windowParams?.width = (ScreenUtils.getWindowSize().x * 0.8).toInt()
|
||||
dialog?.window?.attributes = windowParams
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
dialog?.setCancelable(false)
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val view = layoutInflater.inflate(R.layout.dialog_privacy_policy, null)
|
||||
|
||||
binding = DialogPrivacyPolicyBinding.bind(view)
|
||||
binding.tvTitle.typeface = Constants.youSheBiaoTiHei
|
||||
|
||||
binding.btnNext.onClick {
|
||||
mOnBackListener?.invoke(DialogEnum.CLICK_OK)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
binding.btnDisagree.onClick {
|
||||
mOnBackListener?.invoke(DialogEnum.CLICK_CANCEL)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
initAgreement()
|
||||
|
||||
val dialog = Dialog(requireContext())
|
||||
dialog.setContentView(view)
|
||||
return dialog
|
||||
}
|
||||
|
||||
fun setOnSelectListener(listener: ((DialogEnum) -> Unit)) {
|
||||
mOnBackListener = listener
|
||||
}
|
||||
|
||||
private fun initAgreement() {
|
||||
SpanUtils.with(binding.tvContent)
|
||||
.append("请你务必审慎阅读、充分理解")
|
||||
.append("《服务协议》")
|
||||
.setBold()
|
||||
.setClickSpan(getColor(R.color.color_466afd), false) {
|
||||
UrlHelper.startUserAgreement(requireContext())
|
||||
}
|
||||
.append("和")
|
||||
.append("《隐私政策》")
|
||||
.setBold()
|
||||
.setClickSpan(getColor(R.color.color_466afd), false) {
|
||||
UrlHelper.startPrivacyPolicy(requireContext())
|
||||
}
|
||||
.append("各条款,包括但不限于:为了更好的向你提供服务,我们需要访问你的相册、位置信息等。你可阅读")
|
||||
.append("《隐私政策》")
|
||||
.setBold()
|
||||
.setClickSpan(getColor(R.color.color_466afd), false) {
|
||||
UrlHelper.startPrivacyPolicy(requireContext())
|
||||
}
|
||||
.append("了解详细信息。如果你同意,请点击下面同意按钮开始接受我们的服务。")
|
||||
.create()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
package com.cheng.bole.ui.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Dialog
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter
|
||||
import com.chad.library.adapter.base.viewholder.BaseViewHolder
|
||||
import com.example.base.extensions.getColor
|
||||
import com.example.base.extensions.getYYYYMMDD2
|
||||
import com.example.base.extensions.gone
|
||||
import com.example.base.extensions.onClick
|
||||
import com.example.base.extensions.visible
|
||||
import com.example.base.utils.ScreenUtils
|
||||
import com.example.base.utils.SpanUtils
|
||||
import com.example.base.widget.EmptyView
|
||||
import com.example.base.widget.PageStatus
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.common.Constants
|
||||
import com.cheng.bole.databinding.DialogSelectCouponBinding
|
||||
import com.cheng.bole.ui.fragment.mine.vip.VipFragment
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class SelectCouponDialog : DialogFragment() {
|
||||
private val id by lazy { arguments?.getString("id") ?: "" }
|
||||
private val price by lazy { arguments?.getString("price") ?: "" }
|
||||
|
||||
private val mAdapter by lazy { CouponAdapter(price) }
|
||||
private val mEmptyView by lazy { EmptyView(requireContext()) }
|
||||
private var mOnBackListener: ((com.cheng.bole.bean.CouponEntity?) -> Unit)? = null
|
||||
private var selectedCoupon: com.cheng.bole.bean.CouponEntity? = null
|
||||
|
||||
lateinit var binding: DialogSelectCouponBinding
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val window = dialog?.window
|
||||
val windowParams = window?.attributes
|
||||
windowParams?.dimAmount = 0.7f
|
||||
windowParams?.width = ScreenUtils.getWindowSize().x
|
||||
windowParams?.gravity = Gravity.BOTTOM
|
||||
windowParams?.windowAnimations = R.style.dialog_bottom
|
||||
dialog?.window?.attributes = windowParams
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val view = layoutInflater.inflate(R.layout.dialog_select_coupon, null)
|
||||
|
||||
binding = DialogSelectCouponBinding.bind(view)
|
||||
|
||||
binding.mRecyclerView.adapter = mAdapter
|
||||
mEmptyView.setBtnVisible(false)
|
||||
mAdapter.setEmptyView(mEmptyView)
|
||||
|
||||
mAdapter.setOnItemClickListener { _, _, i ->
|
||||
val item = mAdapter.getItem(i)
|
||||
if (TextUtils.isEmpty(item.threshold) || item.threshold.toFloat() / 100 <= price.toFloat()) {
|
||||
mAdapter.data.forEach {
|
||||
if (it.id == item.id) {
|
||||
it.isChecked = !it.isChecked
|
||||
} else {
|
||||
it.isChecked = false
|
||||
}
|
||||
}
|
||||
selectedCoupon = if (item.isChecked) item else null
|
||||
mAdapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
binding.ivClose.onClick {
|
||||
dismiss()
|
||||
}
|
||||
binding.btnNext.onClick {
|
||||
mOnBackListener?.invoke(selectedCoupon)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
initData()
|
||||
|
||||
val dialog = Dialog(requireContext())
|
||||
dialog.setContentView(view)
|
||||
return dialog
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun initData() {
|
||||
val fragment = requireParentFragment()
|
||||
if (fragment is VipFragment) {
|
||||
fragment.mViewModel.couponListLiveData.observe(this) { list ->
|
||||
mAdapter.setList(list)
|
||||
mAdapter.data.forEach {
|
||||
if (it.id == id) {
|
||||
it.isChecked = true
|
||||
selectedCoupon = it
|
||||
}
|
||||
}
|
||||
mAdapter.notifyDataSetChanged()
|
||||
if (mAdapter.data.isEmpty()) {
|
||||
mEmptyView.setStatus(PageStatus.NO_DATA)
|
||||
binding.layoutBottom.gone()
|
||||
} else {
|
||||
mEmptyView.setStatus(PageStatus.GONG)
|
||||
binding.layoutBottom.visible()
|
||||
}
|
||||
}
|
||||
fragment.mViewModel.couponList()
|
||||
}
|
||||
}
|
||||
|
||||
fun setOnBackListener(listener: (com.cheng.bole.bean.CouponEntity?) -> Unit) {
|
||||
mOnBackListener = listener
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(id: String?, price: String): SelectCouponDialog {
|
||||
val args = Bundle()
|
||||
args.putString("id", id)
|
||||
args.putString("price", price)
|
||||
val fragment = SelectCouponDialog()
|
||||
fragment.arguments = args
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
|
||||
internal class CouponAdapter(private val price: String) : BaseQuickAdapter<com.cheng.bole.bean.CouponEntity, BaseViewHolder>(R.layout.listitem_coupon_dialog) {
|
||||
|
||||
override fun convert(holder: BaseViewHolder, item: com.cheng.bole.bean.CouponEntity) {
|
||||
holder.setText(
|
||||
R.id.tv_name,
|
||||
if (!TextUtils.isEmpty(item.coupon_name)) item.coupon_name else "${item.coupon_value_name}${item.coupon_type_name}"
|
||||
)
|
||||
holder.setText(R.id.tv_expire_time, "有效期至 ${(item.expire_timestamp.toLong() * 1000).getYYYYMMDD2()}")
|
||||
holder.setText(R.id.tv_type, item.coupon_type_name)
|
||||
holder.getView<TextView>(R.id.tv_discount_amount).typeface = Constants.dDIN_PRO_M
|
||||
when (item.coupon_type) {
|
||||
com.cheng.bole.bean.CouponEntity.TYPE_CASH -> {
|
||||
SpanUtils.with(holder.getView(R.id.tv_discount_amount))
|
||||
.append("¥")
|
||||
.setFontSize(12, true)
|
||||
.append(DecimalFormat("0.##").format(item.coupon_value.toFloat() / 100))
|
||||
.create()
|
||||
if (!TextUtils.isEmpty(item.threshold)) {
|
||||
holder.setText(R.id.tv_threshold_amount, "满${DecimalFormat("0.##").format(item.threshold.toFloat() / 100)}可用")
|
||||
} else {
|
||||
holder.setText(R.id.tv_threshold_amount, "无门槛")
|
||||
}
|
||||
}
|
||||
|
||||
com.cheng.bole.bean.CouponEntity.TYPE_DISCOUNT -> {
|
||||
SpanUtils.with(holder.getView(R.id.tv_discount_amount))
|
||||
.append(DecimalFormat("0.##").format(item.coupon_value.toFloat() * 10))
|
||||
.append("折")
|
||||
.setFontSize(12, true)
|
||||
.create()
|
||||
if (!TextUtils.isEmpty(item.threshold)) {
|
||||
holder.setText(R.id.tv_threshold_amount, "满${DecimalFormat("0.##").format(item.threshold.toFloat() / 100)}可用")
|
||||
} else {
|
||||
holder.setText(R.id.tv_threshold_amount, "无门槛")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(item.threshold) || item.threshold.toFloat() / 100 <= price.toFloat()) {
|
||||
holder.setTextColor(R.id.tv_discount_amount, getColor(R.color.color_ff5846))
|
||||
holder.setTextColor(R.id.tv_threshold_amount, getColor(R.color.color_ff5846))
|
||||
holder.setBackgroundResource(R.id.layout_amount, R.drawable.shape_fdf4f2_cor6)
|
||||
holder.setImageResource(R.id.iv_check, if (item.isChecked) R.mipmap.ic_coupon_check_true else R.mipmap.ic_coupon_check_false)
|
||||
} else {
|
||||
holder.setTextColor(R.id.tv_discount_amount, getColor(R.color.color_d8d8d8))
|
||||
holder.setTextColor(R.id.tv_threshold_amount, getColor(R.color.color_d8d8d8))
|
||||
holder.setBackgroundResource(R.id.layout_amount, R.drawable.shape_f6f6f6_cor6)
|
||||
holder.setImageResource(R.id.iv_check, R.mipmap.ic_coupon_check_disable)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package com.cheng.bole.ui.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.example.base.extensions.onClick
|
||||
import com.example.base.extensions.toast
|
||||
import com.example.base.utils.ClipboardUtils
|
||||
import com.example.base.utils.ScreenUtils
|
||||
import com.tencent.mm.opensdk.openapi.IWXAPI
|
||||
import com.tencent.mm.opensdk.openapi.WXAPIFactory
|
||||
import com.umeng.socialize.bean.SHARE_MEDIA
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.common.Constants
|
||||
import com.cheng.bole.common.EventConstants
|
||||
import com.cheng.bole.databinding.DialogShareBinding
|
||||
import com.cheng.bole.manager.EventReportManager
|
||||
import com.cheng.bole.manager.ShareManager
|
||||
import com.cheng.bole.manager.UserConfigManager
|
||||
|
||||
class ShareDialog : DialogFragment() {
|
||||
private lateinit var api: IWXAPI
|
||||
|
||||
lateinit var binding: DialogShareBinding
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val window = dialog?.window
|
||||
val windowParams = window?.attributes
|
||||
windowParams?.dimAmount = 0.7f
|
||||
windowParams?.width = ScreenUtils.getWindowSize().x
|
||||
windowParams?.gravity = Gravity.BOTTOM
|
||||
windowParams?.windowAnimations = R.style.dialog_bottom
|
||||
dialog?.window?.attributes = windowParams
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
api = WXAPIFactory.createWXAPI(requireContext(), Constants.WechatAppId)
|
||||
|
||||
val view = layoutInflater.inflate(R.layout.dialog_share, null)
|
||||
binding = DialogShareBinding.bind(view)
|
||||
|
||||
binding.ivWxShare.onClick {
|
||||
if (!api.isWXAppInstalled) {
|
||||
toast("您没有安装微信客户端,请先下载安装")
|
||||
return@onClick
|
||||
}
|
||||
ShareManager.shareUrl(requireActivity(), SHARE_MEDIA.WEIXIN, UserConfigManager.getShareEntity()!!) {}
|
||||
EventReportManager.eventReport(EventConstants.SHARE_APP, "", "weixin")
|
||||
dismiss()
|
||||
}
|
||||
|
||||
binding.ivWxCircleShare.onClick {
|
||||
if (!api.isWXAppInstalled) {
|
||||
toast("您没有安装微信客户端,请先下载安装")
|
||||
return@onClick
|
||||
}
|
||||
ShareManager.shareUrl(requireActivity(), SHARE_MEDIA.WEIXIN_CIRCLE, UserConfigManager.getShareEntity()!!) {}
|
||||
EventReportManager.eventReport(EventConstants.SHARE_APP, "", "weixin_friend")
|
||||
dismiss()
|
||||
}
|
||||
|
||||
binding.ivLinkShare.onClick {
|
||||
ClipboardUtils.copyText(UserConfigManager.getShareEntity()!!.link)
|
||||
EventReportManager.eventReport(EventConstants.SHARE_APP, "", "copy_url")
|
||||
toast("复制成功")
|
||||
dismiss()
|
||||
}
|
||||
|
||||
val dialog = Dialog(requireContext())
|
||||
dialog.setContentView(view)
|
||||
return dialog
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
package com.cheng.bole.ui.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.example.base.extensions.gone
|
||||
import com.example.base.extensions.onClick
|
||||
import com.example.base.extensions.visible
|
||||
import com.example.base.utils.ScreenUtils
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.databinding.DialogSimpleTipBinding
|
||||
import com.cheng.bole.manager.DialogEnum
|
||||
|
||||
class SimpleTipDialog : DialogFragment() {
|
||||
|
||||
private var mOnBackListener: ((DialogEnum) -> Unit)? = null //回调事件
|
||||
|
||||
private var content: CharSequence? = null
|
||||
private var leftText: String? = null
|
||||
private var rightText: String? = null
|
||||
|
||||
lateinit var binding: DialogSimpleTipBinding
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val window = dialog?.window
|
||||
val windowParams = window?.attributes
|
||||
windowParams?.dimAmount = 0.7f
|
||||
windowParams?.width = (ScreenUtils.getWindowSize().x * 0.8).toInt()
|
||||
dialog?.window?.attributes = windowParams
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val view = layoutInflater.inflate(R.layout.dialog_simple_tip, null)
|
||||
|
||||
binding = DialogSimpleTipBinding.bind(view)
|
||||
|
||||
content = arguments?.getCharSequence("content")
|
||||
leftText = arguments?.getString("leftText")
|
||||
rightText = arguments?.getString("rightText")
|
||||
|
||||
if (!TextUtils.isEmpty(content)) {
|
||||
binding.tvContent.text = content
|
||||
}
|
||||
if (!TextUtils.isEmpty(leftText)) {
|
||||
binding.tvCancel.text = leftText
|
||||
binding.tvCancel.visible()
|
||||
} else {
|
||||
binding.tvCancel.gone()
|
||||
}
|
||||
if (!TextUtils.isEmpty(rightText)) {
|
||||
binding.tvOk.text = rightText
|
||||
}
|
||||
|
||||
binding.tvCancel.onClick {
|
||||
mOnBackListener?.invoke(DialogEnum.CLICK_CANCEL)
|
||||
dismiss()
|
||||
}
|
||||
binding.tvOk.onClick {
|
||||
mOnBackListener?.invoke(DialogEnum.CLICK_OK)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
val dialog = Dialog(requireContext())
|
||||
dialog.setContentView(view)
|
||||
return dialog
|
||||
}
|
||||
|
||||
fun setOnSelectListener(listener: ((DialogEnum) -> Unit)) {
|
||||
mOnBackListener = listener
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(
|
||||
content: CharSequence? = null,
|
||||
leftText: String? = null,
|
||||
rightText: String? = null,
|
||||
): SimpleTipDialog {
|
||||
val arg = Bundle()
|
||||
val fragment = SimpleTipDialog()
|
||||
arg.putCharSequence("content", content)
|
||||
arg.putString("leftText", leftText)
|
||||
arg.putString("rightText", rightText)
|
||||
fragment.arguments = arg
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
package com.cheng.bole.ui.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.example.base.extensions.onClick
|
||||
import com.example.base.utils.ScreenUtils
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.common.Constants
|
||||
import com.cheng.bole.databinding.DialogTipBinding
|
||||
import com.cheng.bole.manager.DialogEnum
|
||||
|
||||
class TipDialog : DialogFragment() {
|
||||
|
||||
private var mOnBackListener: ((DialogEnum) -> Unit)? = null //回调事件
|
||||
|
||||
private var title: String? = null
|
||||
private var content: CharSequence? = null
|
||||
private var leftText: String? = null
|
||||
private var rightText: String? = null
|
||||
private var cancelable: Boolean = true
|
||||
|
||||
lateinit var binding: DialogTipBinding
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val window = dialog?.window
|
||||
val windowParams = window?.attributes
|
||||
windowParams?.dimAmount = 0.7f
|
||||
windowParams?.width = (ScreenUtils.getWindowSize().x * 0.8).toInt()
|
||||
dialog?.window?.attributes = windowParams
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
setCancelable(cancelable)
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val view = layoutInflater.inflate(R.layout.dialog_tip, null)
|
||||
|
||||
binding = DialogTipBinding.bind(view)
|
||||
|
||||
binding.tvTitle.typeface = Constants.youSheBiaoTiHei
|
||||
|
||||
title = arguments?.getString("title")
|
||||
content = arguments?.getCharSequence("content")
|
||||
leftText = arguments?.getString("leftText")
|
||||
rightText = arguments?.getString("rightText")
|
||||
cancelable = arguments?.getBoolean("cancelable") ?: true
|
||||
|
||||
if (!TextUtils.isEmpty(title)) {
|
||||
binding.tvTitle.text = title
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(content)) {
|
||||
binding.tvContent.text = content
|
||||
}
|
||||
if (!TextUtils.isEmpty(leftText)) {
|
||||
binding.tvCancel.text = leftText
|
||||
}
|
||||
if (!TextUtils.isEmpty(rightText)) {
|
||||
binding.tvOk.text = rightText
|
||||
}
|
||||
|
||||
binding.tvCancel.onClick {
|
||||
mOnBackListener?.invoke(DialogEnum.CLICK_CANCEL)
|
||||
dismiss()
|
||||
}
|
||||
binding.tvOk.onClick {
|
||||
mOnBackListener?.invoke(DialogEnum.CLICK_OK)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
val dialog = Dialog(requireContext())
|
||||
dialog.setContentView(view)
|
||||
return dialog
|
||||
}
|
||||
|
||||
fun setOnSelectListener(listener: ((DialogEnum) -> Unit)) {
|
||||
mOnBackListener = listener
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(
|
||||
title: String? = null,
|
||||
content: CharSequence? = null,
|
||||
leftText: String? = null,
|
||||
rightText: String? = null,
|
||||
cancelable: Boolean = true
|
||||
): TipDialog {
|
||||
val arg = Bundle()
|
||||
val fragment = TipDialog()
|
||||
arg.putString("title", title)
|
||||
arg.putCharSequence("content", content)
|
||||
arg.putString("leftText", leftText)
|
||||
arg.putString("rightText", rightText)
|
||||
arg.putBoolean("cancelable", cancelable)
|
||||
fragment.arguments = arg
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
package com.cheng.bole.ui.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Dialog
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.common.EventConstants
|
||||
import com.cheng.bole.databinding.DialogUpdateVerisonBinding
|
||||
import com.cheng.bole.manager.DialogEnum
|
||||
import com.cheng.bole.manager.EventReportManager
|
||||
import com.cheng.bole.utils.DownLoadUtils
|
||||
import com.cheng.bole.utils.PermissionUtils
|
||||
import com.cheng.bole.utils.UIUtils
|
||||
import com.example.base.extensions.gone
|
||||
import com.example.base.extensions.onClick
|
||||
import com.example.base.extensions.visible
|
||||
import com.example.base.utils.ScreenUtils
|
||||
import com.cheng.bole.common.Constants
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
|
||||
class UpdateVersionDialog : DialogFragment() {
|
||||
private var mOnBackListener: ((DialogEnum) -> Unit)? = null //回调事件
|
||||
|
||||
var apkFilePath = ""
|
||||
|
||||
lateinit var binding: DialogUpdateVerisonBinding
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val window = dialog?.window
|
||||
val windowParams = window?.attributes
|
||||
windowParams?.dimAmount = 0.7f
|
||||
windowParams?.width = (ScreenUtils.getWindowSize().x * 0.7).toInt()
|
||||
dialog?.window?.attributes = windowParams
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val view = layoutInflater.inflate(R.layout.dialog_update_verison, null)
|
||||
|
||||
binding = DialogUpdateVerisonBinding.bind(view)
|
||||
|
||||
binding.tvUpdateTitle.typeface = Constants.youSheBiaoTiHei
|
||||
|
||||
val versionEntity = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
arguments?.getSerializable("versionEntity", com.cheng.bole.bean.VersionEntity::class.java)
|
||||
} else {
|
||||
arguments?.getSerializable("versionEntity") as com.cheng.bole.bean.VersionEntity?
|
||||
}
|
||||
|
||||
binding.cancelBtn.onClick {
|
||||
dismiss()
|
||||
EventReportManager.eventReport(EventConstants.PKG_CANCEL, "", "升级的版本号${versionEntity?.version}")
|
||||
}
|
||||
|
||||
versionEntity?.apply {
|
||||
binding.tvVersionName.text = version
|
||||
binding.tvUpdateTitle.text = title
|
||||
binding.tvUpdateDesc.text = description
|
||||
if (force) {
|
||||
binding.cancelBtn.gone()
|
||||
} else {
|
||||
binding.cancelBtn.visible()
|
||||
}
|
||||
}
|
||||
|
||||
binding.ivClose.onClick {
|
||||
val f = TipDialog.newInstance("提示", "确定取消下载?")
|
||||
f.setOnSelectListener {
|
||||
if (it == DialogEnum.CLICK_OK) {
|
||||
DownLoadUtils.getInstance().cancel()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
f.show(childFragmentManager, TipDialog::class.java.simpleName)
|
||||
}
|
||||
|
||||
binding.updateBtn.onClick {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
if (binding.updateBtn.text.toString() == "立即安裝" && !TextUtils.isEmpty(apkFilePath)) {
|
||||
install()
|
||||
} else {
|
||||
versionEntity?.apply {
|
||||
download(url, force)
|
||||
EventReportManager.eventReport(EventConstants.PKG_UPDATE, "", "升级的版本号${versionEntity.version}")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PermissionUtils.checkStoragePermission(requireActivity(), childFragmentManager) { isGranted ->
|
||||
if (isGranted) {
|
||||
if (binding.updateBtn.text.toString() == "立即安裝" && !TextUtils.isEmpty(apkFilePath)) {
|
||||
install()
|
||||
} else {
|
||||
versionEntity?.apply {
|
||||
download(url, force)
|
||||
EventReportManager.eventReport(EventConstants.PKG_UPDATE, "", "升级的版本号${versionEntity.version}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isCancelable = false
|
||||
|
||||
val dialog = Dialog(requireContext())
|
||||
dialog.setContentView(view)
|
||||
dialog.setCancelable(false)
|
||||
dialog.setCanceledOnTouchOutside(false)
|
||||
return dialog
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun download(url: String, force: Boolean) {
|
||||
|
||||
if (force) {
|
||||
binding.ivClose.gone()
|
||||
} else {
|
||||
binding.ivClose.visible()
|
||||
}
|
||||
binding.cancelBtn.gone()
|
||||
binding.updateBtn.gone()
|
||||
binding.progressbar.visible()
|
||||
binding.tvProgress.visible()
|
||||
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
var totalProgress = 0L
|
||||
DownLoadUtils.getInstance()
|
||||
.setReadTImeOut(10L)
|
||||
.setDeleteWhenException(false)
|
||||
.initUrl(url, null)
|
||||
.setFilePath(com.cheng.bole.utils.FileUtils.getInstance().cacheDownLoderDir.absolutePath)
|
||||
.setFileName(UIUtils.getFileNameFromUrl(url))
|
||||
.setActionCallBack(
|
||||
{ totalProgress = it },
|
||||
{
|
||||
val percent = it.toDouble() / totalProgress.toDouble() * 100
|
||||
val curProgress = percent.toInt()
|
||||
binding.tvProgress.text = "${curProgress}%"
|
||||
binding.progressbar.progress = curProgress
|
||||
},
|
||||
{
|
||||
binding.tvProgress.text = "100%"
|
||||
apkFilePath = it.absolutePath
|
||||
binding.updateBtn.text = "立即安裝"
|
||||
|
||||
binding.updateBtn.visible()
|
||||
binding.progressbar.gone()
|
||||
binding.tvProgress.gone()
|
||||
|
||||
install()
|
||||
}, {
|
||||
binding.updateBtn.text = "下载失败,点击重试"
|
||||
binding.updateBtn.visible()
|
||||
binding.progressbar.gone()
|
||||
binding.tvProgress.gone()
|
||||
}).down()
|
||||
}
|
||||
}
|
||||
|
||||
fun setOnSelectListener(listener: ((DialogEnum) -> Unit)) {
|
||||
mOnBackListener = listener
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(versionEntity: com.cheng.bole.bean.VersionEntity): UpdateVersionDialog {
|
||||
val arg = Bundle()
|
||||
val fragment = UpdateVersionDialog()
|
||||
arg.putSerializable("versionEntity", versionEntity)
|
||||
fragment.arguments = arg
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
|
||||
private fun install() {
|
||||
try {
|
||||
val apkFile = File(com.cheng.bole.utils.FileUtils.getInstance().cacheDownLoderDir, UIUtils.getFileNameFromUrl(apkFilePath))
|
||||
if (!apkFile.exists()) {
|
||||
return
|
||||
}
|
||||
val apkUri = FileProvider.getUriForFile(requireContext(), requireContext().packageName + ".fileprovider", apkFile)
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
|
||||
startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.cheng.bole.ui.dialog
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.example.base.extensions.onClick
|
||||
import com.example.base.utils.ScreenUtils
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.common.Constants
|
||||
import com.cheng.bole.databinding.DialogVipLoginTipBinding
|
||||
import com.cheng.bole.ui.base.BaseDialog
|
||||
|
||||
class VipLoginTipDialog(mFragment: Fragment) : BaseDialog(mFragment.requireContext()){
|
||||
private var mOnBackListener: (() -> Unit)? = null //回调事件
|
||||
|
||||
lateinit var binding: DialogVipLoginTipBinding
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val view = layoutInflater.inflate(R.layout.dialog_vip_login_tip, null)
|
||||
setContentView(view)
|
||||
|
||||
val windowParams = window?.attributes
|
||||
windowParams?.dimAmount = 0.7f
|
||||
windowParams?.width = (ScreenUtils.getWindowSize().x * 0.8).toInt()
|
||||
window?.attributes = windowParams
|
||||
|
||||
setCancelable(false)
|
||||
|
||||
binding = DialogVipLoginTipBinding.bind(view)
|
||||
|
||||
binding.tvTitle.typeface = Constants.youSheBiaoTiHei
|
||||
|
||||
binding.btnOk.onClick {
|
||||
mOnBackListener?.invoke()
|
||||
dismiss()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun setOnSelectListener(listener: (() -> Unit)) {
|
||||
mOnBackListener = listener
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
package com.cheng.bole.ui.fragment.guide
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
|
||||
import com.example.base.extensions.gone
|
||||
import com.example.base.extensions.onClick
|
||||
import com.example.base.ui.BaseFragment
|
||||
import com.cheng.bole.ui.activity.MainActivity
|
||||
import com.cheng.bole.ui.activity.PublicActivity
|
||||
import com.cheng.bole.common.Constants
|
||||
import com.cheng.bole.common.EventConstants
|
||||
import com.cheng.bole.databinding.FragmentGuideContentBinding
|
||||
import com.cheng.bole.manager.EventReportManager
|
||||
import com.cheng.bole.manager.UserConfigManager
|
||||
import com.cheng.bole.ui.base.BasePageAdapter
|
||||
import com.cheng.bole.ui.fragment.mine.vip.VipFragment
|
||||
import org.jetbrains.anko.startActivity
|
||||
|
||||
class GuideFragment :BaseFragment<FragmentGuideContentBinding, GuideViewModel>(){
|
||||
|
||||
private var titles = listOf("guide1", "guide2", "guide3","guide4")
|
||||
|
||||
private val list by lazy {
|
||||
ArrayList<Fragment>()
|
||||
}
|
||||
|
||||
private val indicatorAdapter by lazy { IndicatorAdapter() }
|
||||
|
||||
private var mIsScrolled = false
|
||||
private var currentPosition = 0
|
||||
|
||||
override fun initView() {
|
||||
super.initView()
|
||||
titles.forEachIndexed { index, s ->
|
||||
list.add(GuideItemFragment.newInstance(index))
|
||||
}
|
||||
val pageAdapter = BasePageAdapter(childFragmentManager, titles, list)
|
||||
binding.viewPager.adapter = pageAdapter
|
||||
binding.viewPager.offscreenPageLimit = list.size
|
||||
|
||||
indicatorAdapter.setList(MutableList(titles.size) { i -> i })
|
||||
binding.rvIndicator.adapter = indicatorAdapter
|
||||
|
||||
binding.tvTitle.typeface = Constants.almmsht
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
super.initData()
|
||||
binding.tvDesc.text = UserConfigManager.getGuideHint()
|
||||
EventReportManager.eventReport(EventConstants.GUIDE_LAUNCH, "", "")
|
||||
}
|
||||
|
||||
override fun initListener() {
|
||||
super.initListener()
|
||||
binding.btnStart.onClick {
|
||||
binding.btnStart.postDelayed({
|
||||
binding.layoutGuide.gone()
|
||||
}, 200)
|
||||
}
|
||||
|
||||
binding.viewPager.addOnPageChangeListener(object :OnPageChangeListener{
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun onPageSelected(position: Int) {
|
||||
currentPosition = position
|
||||
indicatorAdapter.currentIndex = currentPosition
|
||||
indicatorAdapter.notifyDataSetChanged()
|
||||
EventReportManager.eventReport(EventConstants.GUIDE_OPPORTUNITY_SCROLL, "${currentPosition + 1}", "")
|
||||
}
|
||||
|
||||
override fun onPageScrollStateChanged(state: Int) {
|
||||
when(state){
|
||||
ViewPager.SCROLL_STATE_DRAGGING->{
|
||||
mIsScrolled = false
|
||||
return
|
||||
}
|
||||
ViewPager.SCROLL_STATE_SETTLING->{
|
||||
mIsScrolled = true
|
||||
return
|
||||
}
|
||||
ViewPager.SCROLL_STATE_IDLE->{
|
||||
if (!mIsScrolled && currentPosition == indicatorAdapter.itemCount - 1){
|
||||
if (UserConfigManager.getGuidePayEnable()){
|
||||
PublicActivity.start(requireActivity(), VipFragment::class.java, Pair("origin", "guide"))
|
||||
}else{
|
||||
requireActivity().startActivity<MainActivity>()
|
||||
}
|
||||
}
|
||||
mIsScrolled = true
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.cheng.bole.ui.fragment.guide
|
||||
|
||||
import android.os.Bundle
|
||||
import com.cheng.bole.R
|
||||
import com.cheng.bole.databinding.FragmentGuideItemBinding
|
||||
import com.example.base.ui.BaseFragment
|
||||
|
||||
class GuideItemFragment : BaseFragment<FragmentGuideItemBinding, GuideViewModel>() {
|
||||
private val curPos by lazy { arguments?.getInt("curPos") ?: 0 }
|
||||
|
||||
companion object {
|
||||
fun newInstance(pos: Int): GuideItemFragment {
|
||||
val bundle = Bundle()
|
||||
bundle.putInt("curPos", pos)
|
||||
val f = GuideItemFragment()
|
||||
f.arguments = bundle
|
||||
return f
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
super.initView()
|
||||
when (curPos) {
|
||||
0 -> binding.ivGuide.setBackgroundResource(R.mipmap.ic_guide_1)
|
||||
1 -> binding.ivGuide.setBackgroundResource(R.mipmap.ic_guide_2)
|
||||
2 -> binding.ivGuide.setBackgroundResource(R.mipmap.ic_guide_3)
|
||||
3 -> binding.ivGuide.setBackgroundResource(R.mipmap.ic_guide_4)
|
||||
}
|
||||
}
|
||||
|
||||
override fun initListener() {
|
||||
super.initListener()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package com.cheng.bole.ui.fragment.guide
|
||||
|
||||
import com.example.base.viewmodel.BaseViewModel
|
||||
|
||||
class GuideViewModel :BaseViewModel(){
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.cheng.bole.ui.fragment.guide
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter
|
||||
import com.chad.library.adapter.base.viewholder.BaseViewHolder
|
||||
import com.cheng.bole.R
|
||||
|
||||
class IndicatorAdapter: BaseQuickAdapter<Int, BaseViewHolder>(R.layout.listitem_indicator) {
|
||||
var currentIndex = 0
|
||||
|
||||
override fun convert(holder: BaseViewHolder, item: Int) {
|
||||
holder.setImageResource(R.id.iv_indicator, if (item == currentIndex) R.drawable.shape_indicator_select else R.drawable.shape_indicator_default)
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue