commit 3bd8794363e0aea09905d023642598fb0c6ed8f7 Author: 马超 <871197610@qq.com> Date: Tue Mar 12 10:13:13 2024 +0800 首次提交 diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..c82c6ab --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,103 @@ +plugins { + id 'com.android.application' +} + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.ycgis.macall.personalcenter" + minSdkVersion 23 + targetSdkVersion 30 + versionCode 2401171 + versionName "3.0.20240117" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + debug{ + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + buildFeatures { + viewBinding true + dataBinding true + } + packagingOptions { + exclude 'META-INF/XXX' + exclude 'META-INF/proguard/androidx-annotations.pro' + exclude 'META-INF/DEPENDENCIES.txt' + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/NOTICE.txt' + exclude 'META-INF/NOTICE' + exclude 'META-INF/LICENSE' + exclude 'META-INF/DEPENDENCIES' + exclude 'META-INF/notice.txt' + exclude 'META-INF/license.txt' + exclude 'META-INF/dependencies.txt' + exclude 'META-INF/LGPL2.1' + } +} + +dependencies { + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:2.0.1' + testImplementation 'junit:junit:4.+' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + +// tableLayout + implementation 'io.github.h07000223:flycoTabLayout:3.0.0' + //选择组件 + implementation 'com.contrarywind:Android-PickerView:4.1.9' + //轮播图 + implementation 'io.github.youth5201314:banner:2.2.2' + //加载动画 + implementation 'com.wang.avi:library:2.1.3' + //视频播放器 饺子视频播放器 + implementation 'cn.jzvd:jiaozivideoplayer:7.7.0' + + implementation 'com.github.Justson.AgentWeb:agentweb-core:v5.0.6-androidx' // (必选) + implementation 'com.github.Justson.AgentWeb:agentweb-filechooser:v5.0.6-androidx' // (可选) + implementation 'com.github.Justson:Downloader:v5.0.4-androidx' + + //rxJava + retrofit + implementation 'io.reactivex.rxjava2:rxjava:2.2.4' + implementation 'io.reactivex.rxjava2:rxandroid:2.1.0' + implementation 'com.squareup.retrofit2:retrofit:2.6.1' + implementation 'com.squareup.retrofit2:converter-gson:2.6.1' + implementation 'com.squareup.retrofit2:converter-scalars:2.3.0' + implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.1' + + // Glide 设置 OkHttp 请求的注解 依赖 + annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' + + implementation 'com.google.android.material:material:1.5.0-alpha02' + //viewModel + implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation files('libs/com.code.base.jar') + implementation files('libs/AuthSDK_v3.0.0.aar') + implementation files('libs/MarketSDK_v3.0.16.11.aar') + implementation files('libs/unifyservemoduleSDK_V1.5.231221.aar') + implementation files('libs/libfriapkrecord-r1.0.1.aar') + implementation project(':BaseModel') + //Zxing 二维码识别 + implementation 'com.github.jenly1314:zxing-lite:2.1.1' + + +} \ No newline at end of file diff --git a/app/libs/AuthSDK_v3.0.0.aar b/app/libs/AuthSDK_v3.0.0.aar new file mode 100644 index 0000000..6b9d21d Binary files /dev/null and b/app/libs/AuthSDK_v3.0.0.aar differ diff --git a/app/libs/MarketSDK_v3.0.16.11.aar b/app/libs/MarketSDK_v3.0.16.11.aar new file mode 100644 index 0000000..089989c Binary files /dev/null and b/app/libs/MarketSDK_v3.0.16.11.aar differ diff --git a/app/libs/com.code.base.jar b/app/libs/com.code.base.jar new file mode 100644 index 0000000..217510e Binary files /dev/null and b/app/libs/com.code.base.jar differ diff --git a/app/libs/libfriapkrecord-r1.0.1.aar b/app/libs/libfriapkrecord-r1.0.1.aar new file mode 100644 index 0000000..b2fa18e Binary files /dev/null and b/app/libs/libfriapkrecord-r1.0.1.aar differ diff --git a/app/libs/unifyservemoduleSDK_V1.5.231221.aar b/app/libs/unifyservemoduleSDK_V1.5.231221.aar new file mode 100644 index 0000000..2f0bf17 Binary files /dev/null and b/app/libs/unifyservemoduleSDK_V1.5.231221.aar differ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..29f9371 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,281 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile + +#统一认证 +-dontwarn com.anhui.police.auth.** +-keep class com.anhui.police.auth.** { *; } +#应用中心 +-dontwarn com.anhui.police.market.sdk.** +-keep class com.anhui.police.market.** { *; } +#统一服务组件 +-dontwarn com.ruansee.macall.unifyservemodulesdk.** +-keep class com.ruansee.macall.unifyservemodulesdk.** { *; } + +#基类 +-dontwarn com.rs.macall.androidx.basemodel.** +-keep class com.rs.macall.androidx.basemodel.** { *; } + +#加载动画 +-dontwarn com.wang.avi.** +-keep class com.wang.avi.** { *; } + +-keep public class * extends androidx.fragment.app.FragmentActivity +-keep public class * extends android.app.Application +-keep public class * extends androidx.core.content.FileProvider +-keep public class * extends android.app.Service +-keep public class * extends android.app.Activity +-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 class android.support.** {*;} + +-dontwarn java.util.concurrent.Flow* + +-keep public class com.ycgis.macall.personalcenter.p.app.CrashHandler{*;} +-keep public class com.ycgis.macall.personalcenter.p.app.RuanseeApplication{*;} +-keep public class com.ycgis.macall.personalcenter.p.app.UserData{*;} +#-keep public class com.ycgis.macall.personalcenter.p.app.AppCache{*;} +-keep public class com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback{*;} +-keep public class com.ycgis.macall.personalcenter.p.callback.RequestCallback{*;} +-keep public class com.ycgis.macall.personalcenter.p.callback.WebActivityCallback{*;} +-keep public class com.ycgis.macall.personalcenter.p.presenter.**{*;} +-keep public class com.ycgis.macall.personalcenter.p.request.interceptors.**{*;} +-keep public class com.ycgis.macall.personalcenter.p.request.ApiModel{*;} +-keep public class com.ycgis.macall.personalcenter.p.request.HttpErrorHandler{*;} +-keep public class com.ycgis.macall.personalcenter.p.request.RetrofitApi{*;} +-keep public class com.ycgis.macall.personalcenter.p.request.RetrofitService{*;} +-keep public class com.ycgis.macall.personalcenter.p.request.UploadProgressResponsBody{*;} + +-keep public class com.ycgis.macall.personalcenter.m.adapterbean.**{*;} +-keep public class com.ycgis.macall.personalcenter.m.event.MessageEvent{*;} +-keep public class com.ycgis.macall.personalcenter.m.enumbean.**{*;} +-keep public class com.ycgis.macall.personalcenter.m.provider.**{*;} +-keep public class com.ycgis.macall.personalcenter.m.requestbean.**{*;} + +-keep public class com.ycgis.macall.personalcenter.v.activity.**{ +public *;} +-keep public class com.ycgis.macall.personalcenter.v.adapter.**{ +public *;} +-keep public class com.ycgis.macall.personalcenter.v.fragment.**{ +public *;} +-keep public class com.ycgis.macall.personalcenter.v.custom.**{ +public *;} +-keep public class com.ycgis.macall.personalcenter.v.photoview.**{*;} + +-keep public class com.ycgis.macall.personalcenter.util.ReadDeviceInfo{*;} +-keep public class com.ycgis.macall.personalcenter.util.FileUtils{ +public *;} +-keep public class com.ycgis.macall.personalcenter.util.IdcardUtils{ +public *;} +-keep public class com.ycgis.macall.personalcenter.util.JiaMi{*;} +-keep public class com.ycgis.macall.personalcenter.util.ImageOptimizationUtil{*;} +-keep public class com.ycgis.macall.personalcenter.util.IPAddressUtils{*;} +-keep public class com.ycgis.macall.personalcenter.util.LocationGPSManage{ +public *;} +-keep public class com.ycgis.macall.personalcenter.util.NotificationUtils{ +public *;} +-keep public class com.ycgis.macall.personalcenter.util.ToThirdPartyAppUtils{ +public *;} +-keep public class com.ycgis.macall.personalcenter.util.UriUtils{ +public *;} +-keep public class com.ycgis.macall.personalcenter.util.PhoneValidateUtils{*;} + +#-keep public class com.ycgis.macall.personalcenter.v.**{ +# public *; +#} + +-keepclassmembers class com.ycgis.macall.personalcenter.v.activity.OpenAppActivity$AndroidMethodInterface{ *; } + +-keepclassmembers class * extends androidx.fragment.app.FragmentActivity{ + public void *(android.view.View); +} + +-keepclassmembers enum * { *; } + +-keep public class * extends android.view.View{ + *** get*(); + void set*(***); + public (android.content.Context); + public (android.content.Context, android.util.AttributeSet); + public (android.content.Context, android.util.AttributeSet, int); +} +-keepclasseswithmembers class * { + public (android.content.Context, android.util.AttributeSet); + public (android.content.Context, android.util.AttributeSet, int); +} +-keep class **.R$* { + *; +} + +-keepclassmembers class * { + void *(**On*Event); +} + +#OkHttp +-dontwarn okhttp3.** +-keep class okhttp3.**{*;} +-keep interface okhttp3.**{*;} + +#gson +-dontwarn com.google.gson.** +-keep class com.google.gson.** { *;} + +#fastjson +#-keep class com.alibaba.fastjson.** { *; } +#-keep class com.alibaba.fastjson.support.** { *; } + +#EVENT +-keep class org.greenrobot.eventbus.** { *; } + +#luban压缩 +-keep class top.zibin.luban.**{*;} + +#RxJava +-dontwarn sun.misc.** +-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { + long producerIndex; + long consumerIndex; +} + +-dontwarn io.reactivex.android.** +-keepclassmembers class io.reactivex.internal.util.unsafe.*ArrayQueue*Field* { + long producerIndex; + long consumerIndex; +} + +-dontwarn java.lang.invoke.* + +#retrofit +-dontwarn retrofit2.** +-keep class retrofit2.** { *; } +-keepattributes Signature +-keepattributes Exceptions + +-dontwarn com.squareup.** +-dontwarn okio.** +-keep public class org.codehaus.* { *; } +-keep public class java.nio.* { *; } + +-dontwarn butterknife.internal.** +-keep class **$$ViewInjector { *; } + + +#Glide +-keep public class * implements com.bumptech.glide.module.GlideModule +-keep public class * implements com.bumptech.glide.module.AppGlideModule +-keep public class * implements com.bumptech.glide.load.ImageHeaderParser +-keep public enum com.bumptech.glide.load.ImageHeaderParser$*{ + **[] $VALUES; + public *; +} + + +-dontwarn com.bumptech.glide.load.resource.bitmap.VideoDecoder +-dontwarn me.iwf.photopicker.adapter.** + +-keep public class cn.jzvd.JZMediaSystem {*; } + +-keep class tv.danmaku.ijk.media.player.** {*; } +-dontwarn tv.danmaku.ijk.media.player.* +-keep interface tv.danmaku.ijk.media.player.** { *; } + +#Agentweb +-keep class com.just.agentweb.** {*;} +-keep class com.download.** {*;} +-dontwarn com.just.agentweb.** + +-keepclassmembers class **.R$* { + public static ; + public static final int *; +} +-keepclasseswithmembernames class * { # 保持 native 方法不被混淆 + native ; +} +-keepclasseswithmembers class * { # 保持自定义控件类不被混淆 + public (android.content.Context, android.util.AttributeSet); +} +-keepclasseswithmembers class * {# 保持自定义控件类不被混淆 + public (android.content.Context, android.util.AttributeSet, int); +} +-keepclassmembers class * extends android.app.Activity { # 保持自定义控件类不被混淆 + public void *(android.view.View); +} +-keepclassmembers enum * { # 保持枚举 enum 类不被混淆 + public static **[] values(); + public static ** valueOf(java.lang.String); +} +-keep class * implements android.os.Parcelable { # 保持 Parcelable 不被混淆 + public static final android.os.Parcelable$Creator *; +} +-keep public class * extends android.view.View { + public (android.content.Context); + public (android.content.Context, android.util.AttributeSet); + public (android.content.Context, android.util.AttributeSet, int); + public void set*(...); + } +-keepclassmembers public class * extends android.view.View { + void set*(***); + *** get*(); +} + +#Rxjava RxAndroid +-dontwarn rx.* +-dontwarn sun.misc.** +-keepclassmembers class rx.internal.util.unsafe.*ArrayQuene*Field*{ +long producerIndex; +long consumerIndex; +} + + + +#忽略警告 +-ignorewarnings +-keep class javax.ws.rs.** { *; } +-dontwarn com.alibaba.fastjson.** +-keep class com.alibaba.fastjson.** { *; } + +#apk 包内所有 class 的内部结构 +#-dump class_files.txt +#未混淆的类和成员 +#-printseeds seeds.txt +#列出从 apk 中删除的代码 +#-printusage unused.txt +#混淆前后的映射 +#-printmapping mapping.txt + +#fastjson 可以混淆也可以不混淆 +#-keep class javax.ws.rs.** { *; } +#-dontwarn com.alibaba.fastjson.** +#-keep class com.alibaba.fastjson.** { *; } +-keepclassmembers class * implements java.io.Serializable { + static final long serialVersionUID; + private static final java.io.ObjectStreamField[] serialPersistentFields; + private void writeObject(java.io.ObjectOutputStream); + private void readObject(java.io.ObjectInputStream); + java.lang.Object writeReplace(); + java.lang.Object readResolve(); + public ; +} +-keepattributes Signature diff --git a/app/release/H5测试V2.5.apk b/app/release/H5测试V2.5.apk new file mode 100644 index 0000000..0eb94ed Binary files /dev/null and b/app/release/H5测试V2.5.apk differ diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json new file mode 100644 index 0000000..859d7ef --- /dev/null +++ b/app/release/output-metadata.json @@ -0,0 +1,18 @@ +{ + "version": 2, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "com.ruansee.macall.testwebview", + "variantName": "release", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "versionCode": 5, + "versionName": "2.5", + "outputFile": "testwebview-release.apk" + } + ] +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/ycgis/macall/personalcenter/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/ycgis/macall/personalcenter/ExampleInstrumentedTest.java new file mode 100644 index 0000000..59c9268 --- /dev/null +++ b/app/src/androidTest/java/com/ycgis/macall/personalcenter/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.ycgis.macall.personalcenter; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.ycgis.macall.personalcenter", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..92be3c0 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/data/frequentlyQuestions.json b/app/src/main/assets/data/frequentlyQuestions.json new file mode 100644 index 0000000..401abbb --- /dev/null +++ b/app/src/main/assets/data/frequentlyQuestions.json @@ -0,0 +1,77 @@ +[ + { + "title": "应用安装登录问题", + "data": [ + { + "problem": "1、应用中心下载后安装失败?", + "reply": "如果安装包已经下载且点击安装后安装不了的,返回应用中心’首页‘,切换到‘应用管理’,至’安装包管理‘,找到并删除已下载的安装包,然后返回’首页‘重新下载安装应用。\n\t\t如果此操作还是安装不了,建议电话联系应用中心运维人员反馈", + "extend": "查找应用中心运维人员联系方式", + "guidance": "ic_tyrzyw" + }, + { + "problem": "2、登录应用提示设备未绑定?", + "reply": "提示设备未绑定的,如果跳转到了登录页,就在登录页输入警号和密码后进行绑定。\n\t\t未跳转登录页的,先打开’应用中心‘查看是否能正常打开’应用中心‘,如果正常打开,就在应用中心搜索该应用,找到运维人员联系方式进行反馈。\n\t\t未正常打开且不跳转登录页的,请联系市局科信(下发设备的)反馈设备问题。", + "extend": "", + "guidance": "" + } + ] + }, + { + "title": "个人信息问题", + "data": [ + { + "problem": "1、登录应用后显示的用户信息不是本人信息?", + "reply": "有以下几种情况:\n\t\t\t\t1、设备绑定信息问题:即设备绑定的信息是其他民警的,需联系'统一认证'运维人员解绑该设备,然后重新打开'应用中心'登录自己的警号即可。\n\t\t\t\t2、警员库问题:警号是自己的,姓名和身份证号等信息是别人的,这种情况是警员库没有及时更新导致的,需联系'统一认证'运维人员修改信息。\n\t\t\t\t3、警员库问题:警号是自己的、姓名或者身份证号有错误,如身份证号正确,姓名录入错别字的,也需要联系'统一认证'运维人员修改信息。", + "extend": "查找统一认证运维人员联系方式", + "guidance": "ic_tyrzyw" + }, + { + "problem": "2、登录后显示单位不是当前单位?", + "reply": "单位显示的不是当前单位,到我的页面点击上方个人信息,跳转页面后,点击单位名称,跳转后找到当前单位,然后申请调整单位。", + "extend": "", + "guidance": "" + }, + { + "problem": "3、关于个人信息修改", + "reply": "警员信息统一由警综维护,个人中心目前只支持修改联系电话,如果是显示的警号信息和个人信息不符合的参考第1条解决方案。", + "extend": "", + "guidance": "" + } + ] + }, + { + "title": "应用使用相关", + "data": [ + { + "problem": "1、关于自定义应用", + "reply": "自定义应用为了方便快速找到自己想要使用的移动警务应用,实现在’人中心中‘快速开展工作。\n\t\t在首次使用时,点击列表内的+号图标,会读取本机已经安装的移动警务应用列表,民警根据自己需求添加或者移除应用,添加后将在列表中展示该应用,\n\t\t点击已经添加的应用将打开并跳转到该应用。", + "extend": "", + "guidance": "" + }, + { + "problem": "2、关于意见反馈?", + "reply": "民警在使用本应用和应用内的第三方应用时,发现的问题和意见建议都可以在本模块提交。", + "extend": "", + "guidance": "" + }, + { + "problem": "3、关于认证管理", + "reply": "该模块是修改手机上的‘统一认证’的登录方式,目前支持警号密码登录和手势图形登。", + "extend": "", + "guidance": "" + }, + { + "problem": "4、关于应用指南", + "reply": "该模块是展示第三方应用的应用信息、运维信息及上传的操作手册、操作视频、图片等应用相关资料,方便民警快速掌握应用的使用熟悉各应用的使用方法。", + "extend": "", + "guidance": "" + }, + { + "problem": "5、关于应用内第三方应用使用问题", + "reply": "请至'应用指南'中查找到该应用信息,然后联系相关运维人员进行反馈。", + "extend": "", + "guidance": "" + } + ] + } +] \ No newline at end of file diff --git a/app/src/main/assets/font/STXINGKA.TTF b/app/src/main/assets/font/STXINGKA.TTF new file mode 100644 index 0000000..53439a2 Binary files /dev/null and b/app/src/main/assets/font/STXINGKA.TTF differ diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/ActionBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/ActionBean.java new file mode 100644 index 0000000..473928b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/ActionBean.java @@ -0,0 +1,104 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +import android.content.Intent; +import android.os.Bundle; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * created by: Macall + * create time: 2023/5/31 10:50 + * copyright: @ruansee.com + * Describe: + */ +public class ActionBean extends BaseBean{ + private int iconId; + private String name; + private int count; + + private Class aClass; + + private Map param; + + public void addParam(String key,Object value){ + if (param == null)param = new HashMap<>(); + param.put(key,value); + } + + public Map getParam() { + return param; + } + + public int getIconId() { + return iconId; + } + + public void setIconId(int iconId) { + this.iconId = iconId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public Class getaClass() { + return aClass; + } + + public void setaClass(Class aClass) { + this.aClass = aClass; + } + + /** + * 设置跳转参数 + * @param intent intent 意向 + * @return intent 意向 + */ + public Intent setIntentParam(Intent intent){ + if (param!=null&&!param.isEmpty()){ + Set strings = param.keySet(); + for (String key :strings) { + Object o = param.get(key); + if (o instanceof Integer) { + intent.putExtra(key, (int) o); + } else if (o instanceof String) { + intent.putExtra(key, o.toString()); + } else if (o instanceof Boolean) { + intent.putExtra(key, (boolean) o); + } else if (o instanceof Long) { + intent.putExtra(key, (long) o); + } else if (o instanceof Bundle) { + intent.putExtra(key, (Bundle) o); + } else if (o instanceof Byte) { + intent.putExtra(key, (byte) o); + }else if (o instanceof byte[]) { + intent.putExtra(key, (byte[]) o); + }else if (o instanceof Short) { + intent.putExtra(key, (short) o); + }else if (o instanceof Character) { + intent.putExtra(key, (char) o); + }else if (o instanceof String[]) { + intent.putExtra(key, (String[]) o); + }else if (o instanceof Serializable) { + intent.putExtra(key, (Serializable) o); + } + } + } + return intent; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/AppBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/AppBean.java new file mode 100644 index 0000000..9649b80 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/AppBean.java @@ -0,0 +1,200 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +import android.app.Activity; +import android.graphics.drawable.Drawable; + +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.utils.StringUtil; + +/** + * created by: Macall + * create time: 2022/11/7 17:26 + * copyright: @ruansee.com + * Describe: + */ +public class AppBean extends BaseBean{ + private String id; + //省厅应用地市应用 + private String appType; + //治安类、社区类、 + private String classification; + //二类应用、三类应用 + private String networkType; + private String appName; + + private boolean isNew = false; + private int icon; + private Drawable iconDrawable; + + private String iconUrl; + + private String linkUrl; + + private String cityNumber; + private String company; + private String operationName; + private String operationPhone; + + private String time; + + private String clientId; + private String clientSecret; + + private Class activityClass; + + //应用介绍 + private String appIntroduction; + + public Class getActivityClass() { + return activityClass; + } + + public void setActivityClass(Class activityClass) { + this.activityClass = activityClass; + } + + public Drawable getIconDrawable() { + return iconDrawable; + } + + public void setIconDrawable(Drawable iconDrawable) { + this.iconDrawable = iconDrawable; + } + + public String getId() { + return StringUtil.isNullOrEmpty(id)?"":id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCityNumber() { + return cityNumber; + } + + public void setCityNumber(String cityNumber) { + this.cityNumber = cityNumber; + } + + public boolean isNew() { + return isNew; + } + + public void setNew(boolean aNew) { + isNew = aNew; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getClientSecret() { + return clientSecret; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + + public String getLinkUrl() { + return linkUrl; + } + + public void setLinkUrl(String linkUrl) { + this.linkUrl = linkUrl; + } + + public String getAppType() { + return appType; + } + + public void setAppType(String appType) { + this.appType = appType; + } + + public String getClassification() { + return classification; + } + + public void setClassification(String classification) { + this.classification = classification; + } + + public String getNetworkType() { + return networkType; + } + + public void setNetworkType(String networkType) { + this.networkType = networkType; + } + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + } + + public int getIcon() { + return icon; + } + + public void setIcon(int icon) { + this.icon = icon; + } + + public String getIconUrl() { + return iconUrl; + } + + public void setIconUrl(String iconUrl) { + this.iconUrl = iconUrl; + } + + public String getCompany() { + return company; + } + + public void setCompany(String company) { + this.company = company; + } + + public String getOperationName() { + return operationName; + } + + public void setOperationName(String operationName) { + this.operationName = operationName; + } + + public String getOperationPhone() { + return operationPhone; + } + + public void setOperationPhone(String operationPhone) { + this.operationPhone = operationPhone; + } + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + public String getAppIntroduction() { + return appIntroduction; + } + + public void setAppIntroduction(String appIntroduction) { + this.appIntroduction = appIntroduction; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/AppGuideDetailsBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/AppGuideDetailsBean.java new file mode 100644 index 0000000..b11793b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/AppGuideDetailsBean.java @@ -0,0 +1,92 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +import com.google.gson.Gson; +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; + +/** + * created by: Macall + * create time: 2022/11/18 14:23 + * copyright: @ruansee.com + * Describe: + */ +public class AppGuideDetailsBean extends BaseBean implements Serializable { + + /** + * id : 11 + * applicationId : 26 + * applicationName : 一标三实 + * filePath : /profile/upload/2022/11/18/车辆档案结果界面_20221118094523A002.jpg + * type : 1 + * createTime : 2022-11-18 09:45:24 + * updateTime : 2022-11-18 09:45:24 + * remark : null + */ + + @SerializedName("id") + private Integer id; + @SerializedName("applicationId") + private Integer applicationId; + @SerializedName("applicationName") + private String applicationName; + @SerializedName("filePath") + private String filePath; + @SerializedName("type") + private Integer type; + @SerializedName("remark") + private String remark; + + public static AppGuideDetailsBean objectFromData(String str) { + + return new Gson().fromJson(str, AppGuideDetailsBean.class); + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getApplicationId() { + return applicationId; + } + + public void setApplicationId(Integer applicationId) { + this.applicationId = applicationId; + } + + public String getApplicationName() { + return applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + public String getFilePath() { + return filePath; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/AppInfoBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/AppInfoBean.java new file mode 100644 index 0000000..c427a91 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/AppInfoBean.java @@ -0,0 +1,255 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +import com.ycgis.macall.personalcenter.p.app.AppCache; + +/** + * created by: Macall + * create time: 2023/11/14 17:19 + * copyright: @ruansee.com + * Describe: + */ +public class AppInfoBean extends BaseBean{ + /** + * id : 21 + * name : 皖警云核查 + * icon : /profile/upload/2023/01/02/icon_云核查_20230102194657A007.png + * link : null + * packageName : com.ycgis.macall.provinceproject + * effectiveness : 1 + * level : 3 + * classification : null + * type : 1 + * sort : 1 + * cityNumber : null + * serviceProvider : 安徽软思信息技术有限公司 + * operationPerson : 陈乐 + * phoneNumber : 15655166626 + * clientId : 6772242211161756101 + * clientSecret : 82I8I280VX3PCqNqV886y739S2u86i5B + * state : 1 + * remark : null + * applicant : 管理员 + * alarmSignal : admin + * department : 安徽省公安厅 + * applicationTime : 2022-11-16 17:56:23 + * policeDirector : 沙海峰 + * policeDirectorSignal : 006856 + * policePhoneNumber : 15566551515 + * operationGuide : null + * approvalTime : 2022-11-16 17:56:37 + * rejectReason : null + * approver : null + * isRecommend : 0 + * clickCount : 7 + * label : null + * attribution : 0 + */ + + //是否被选中 + private boolean isSelect; + + private int id; + private String name; + private String icon; + private String link; + private String packageName; + private int effectiveness; + //应用级别(1 省厅应用 2 地市应用 3 公共应用) + private int level; + //应用分类(1 行业管理 2 社区警务 3 治安管理) +// private String classification; + //应用类型(1 Ⅱ类应用 2 Ⅲ类应用) + private int type; + //所属省市编号 + private String cityNumber; + //服务厂商 + private String serviceProvider; + //运维人员 + private String operationPerson; + //运维人员联系电话 + private String phoneNumber; + private String clientId; + private String clientSecret; + private String state; + //备注 + private String remark; + //操作指南 + private String operationGuide; + private int isRecommend; + //应用标签(1 人 2 车 3 其它) + private String label; + //0 个人中心应用 1 应用中心 2 共有 + private int attribution; + + public boolean isSelect() { + return isSelect; + } + + public void setSelect(boolean select) { + isSelect = select; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getIcon() { + return icon; + } + + public String getIconUrl() { + return AppCache.BASE_IMAGE_URL+icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public int getEffectiveness() { + return effectiveness; + } + + public void setEffectiveness(int effectiveness) { + this.effectiveness = effectiveness; + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getCityNumber() { + return cityNumber; + } + + public void setCityNumber(String cityNumber) { + this.cityNumber = cityNumber; + } + + public String getServiceProvider() { + return serviceProvider; + } + + public void setServiceProvider(String serviceProvider) { + this.serviceProvider = serviceProvider; + } + + public String getOperationPerson() { + return operationPerson; + } + + public void setOperationPerson(String operationPerson) { + this.operationPerson = operationPerson; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getClientSecret() { + return clientSecret; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getOperationGuide() { + return operationGuide; + } + + public void setOperationGuide(String operationGuide) { + this.operationGuide = operationGuide; + } + + public int getIsRecommend() { + return isRecommend; + } + + public void setIsRecommend(int isRecommend) { + this.isRecommend = isRecommend; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public int getAttribution() { + return attribution; + } + + public void setAttribution(int attribution) { + this.attribution = attribution; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/ApplyAppBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/ApplyAppBean.java new file mode 100644 index 0000000..d8b66a9 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/ApplyAppBean.java @@ -0,0 +1,216 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +import com.ycgis.macall.personalcenter.v.activity.applyfo.ApplyForMainActivity; + +import java.io.Serializable; +import java.util.List; + +/** + * created by: Macall + * create time: 2023/6/3 17:52 + * copyright: @ruansee.com + * Describe: + */ +public class ApplyAppBean implements Serializable { + + /** + * msg : 操作成功 + * code : 200 + * data : [{"createBy":null,"createTime":"2023-06-02 12:11:26","updateBy":null,"updateTime":"2023-06-03 11:30:27","remark":"是的","id":6,"name":"2121","icon":"/profile/upload/2023/06/02/logo_20230602121120A001.png","category":"1","deptId":340100000000,"deptName":"合肥市公安局","status":1,"createUserId":null,"createDeptId":null,"createUserName":null,"createDeptName":null,"roles":[{"createBy":null,"createTime":null,"updateBy":null,"updateTime":null,"remark":null,"id":9,"appId":6,"roleName":"超级管理员"},{"createBy":null,"createTime":null,"updateBy":null,"updateTime":null,"remark":null,"id":10,"appId":6,"roleName":"地市"}]},{"createBy":null,"createTime":"2023-06-02 10:21:31","updateBy":null,"updateTime":"2023-06-03 11:30:27","remark":"这是一个治安应用2023年6月2日10:21:31","id":1,"name":"皖治通","icon":"/profile/upload/2023/06/02/logo_20230602102112A002.png","category":"1","deptId":340100000000,"deptName":"合肥市公安局","status":1,"createUserId":null,"createDeptId":null,"createUserName":null,"createDeptName":null,"roles":[{"createBy":null,"createTime":null,"updateBy":null,"updateTime":null,"remark":null,"id":11,"appId":1,"roleName":"普通用户"},{"createBy":null,"createTime":null,"updateBy":null,"updateTime":null,"remark":null,"id":12,"appId":1,"roleName":"管理员1"}]},{"createBy":null,"createTime":"2023-06-02 11:58:39","updateBy":null,"updateTime":"2023-06-03 11:30:27","remark":"是否","id":5,"name":"11111","icon":"/profile/upload/2023/06/02/logo_20230602115827A002.png","category":"1","deptId":340000000000,"deptName":"安徽省公安厅","status":1,"createUserId":null,"createDeptId":null,"createUserName":null,"createDeptName":null,"roles":[{"createBy":null,"createTime":null,"updateBy":null,"updateTime":null,"remark":null,"id":13,"appId":5,"roleName":"12"}]},{"createBy":null,"createTime":"2023-06-02 10:56:43","updateBy":null,"updateTime":"2023-06-03 11:30:27","remark":"1","id":3,"name":"云搜索","icon":"/profile/upload/2023/06/02/btn_record_20230602105626A002.png","category":"1","deptId":800701750001,"deptName":"安徽省","status":1,"createUserId":null,"createDeptId":null,"createUserName":null,"createDeptName":null,"roles":[{"createBy":null,"createTime":null,"updateBy":null,"updateTime":null,"remark":null,"id":14,"appId":3,"roleName":"23"}]}] + */ + + private String msg; + private int code; + private List data; + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public boolean isSuccess(){ + return code == 200; + } + + public static class DataBean extends BaseBean implements Serializable { + /** + * createBy : null + * createTime : 2023-06-02 12:11:26 + * updateBy : null + * updateTime : 2023-06-03 11:30:27 + * remark : 是的 + * id : 6 + * name : 2121 + * icon : /profile/upload/2023/06/02/logo_20230602121120A001.png + * category : 1 + * deptId : 340100000000 + * deptName : 合肥市公安局 + * status : 1 + * createUserId : null + * createDeptId : null + * createUserName : null + * createDeptName : null + * roles : [{"createBy":null,"createTime":null,"updateBy":null,"updateTime":null,"remark":null,"id":9,"appId":6,"roleName":"超级管理员"},{"createBy":null,"createTime":null,"updateBy":null,"updateTime":null,"remark":null,"id":10,"appId":6,"roleName":"地市"}] + */ + + private int id; + private String name; + private String icon; + private String category; + private long deptId; + private String deptName; + private int status; + private List roles; + private boolean isSelect; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public long getDeptId() { + return deptId; + } + + public void setDeptId(long deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public List getRoles() { + return roles; + } + + public void setRoles(List roles) { + this.roles = roles; + } + + public boolean isSelect() { + return isSelect; + } + + public void setSelect(boolean select) { + isSelect = select; + } + + public String getIconUrl(){ + return ApplyForMainActivity.BASE_PHOTO_URL+icon; + } + + public static class RolesBean extends BaseBean implements Serializable { + /** + * createBy : null + * createTime : null + * updateBy : null + * updateTime : null + * remark : null + * id : 9 + * appId : 6 + * roleName : 超级管理员 + */ + + private int id; + private int appId; + private String roleName; + private boolean isSelect; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getAppId() { + return appId; + } + + public void setAppId(int appId) { + this.appId = appId; + } + + public String getRoleName() { + return roleName; + } + + public void setRoleName(String roleName) { + this.roleName = roleName; + } + + public boolean isSelect() { + return isSelect; + } + + public void setSelect(boolean select) { + isSelect = select; + } + + @Override + public String toString() { + return roleName ; + } + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/ApplyAuditBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/ApplyAuditBean.java new file mode 100644 index 0000000..f443b62 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/ApplyAuditBean.java @@ -0,0 +1,172 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ycgis.macall.personalcenter.R; + +/** + * created by: Macall + * create time: 2023/6/3 11:00 + * copyright: @ruansee.com + * Describe: + */ +public class ApplyAuditBean extends BaseBean { + private String id; + //姓名 + private String auditNickName; + + //警号 + private String auditUserName; + //机构 + private String auditDeptName; + // 2 所在单位 3 所在地市 6 省厅 1 运维 + private String auditUserType; + + //结果 + private String result; + + //0不通过 1 通过 + private int auditStatus; + + //审核意见 + private String opinion; + private String auditTime; + + private String sealStatus; + private String sealDeptId; + + public String getSealStatus() { + return sealStatus; + } + + public void setSealStatus(String sealStatus) { + this.sealStatus = sealStatus; + } + + public String getSealDeptId() { + return sealDeptId; + } + + public void setSealDeptId(String sealDeptId) { + this.sealDeptId = sealDeptId; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getReviewedBy() { + return String.format("%s(%s)",getAuditNickName(),getAuditUserName()); + } + + public int stateBG(){ + if (auditStatus == 0 )return R.drawable.bk_read; + return R.drawable.bk_ls; + } + + public int stateColor(){ + if (auditStatus == 0 )return R.color.colorRed7; + return R.color.colorGreen7; + } + + //1 审核通过 0 待审核 2 分局审核通过 3 市局审核通过 -1 不通过 + public String getStateStr() { + if (auditStatus == 0 )return "不通过"; + return "通过"; + } + + public int getAuditStatus() { + return auditStatus; + } + + public void setAuditStatus(int auditStatus) { + this.auditStatus = auditStatus; + } + + public String getTimeStr() { + return "审批时间:"+getAuditTime(); + } + + public String getAuditNickName() { + return StringUtil.get(auditNickName,"暂无"); + } + + public void setAuditNickName(String auditNickName) { + this.auditNickName = auditNickName; + } + + public String getAuditUserName() { + return StringUtil.get(auditUserName,"暂无"); + } + + public void setAuditUserName(String auditUserName) { + this.auditUserName = auditUserName; + } + + public String getAuditDeptNameStr() { + return "所属部门:"+getAuditDeptName(); + } + + + public String getAuditDeptName() { + return StringUtil.get(auditDeptName,"暂无"); + } + + public void setAuditDeptName(String auditDeptName) { + this.auditDeptName = auditDeptName; + } + + public String getResult() { + return StringUtil.get(result,"暂无"); + } + + public void setResult(String result) { + this.result = result; + } + + public String getOpinionStr() { + return "审核意见:"+StringUtil.get(opinion,"暂无"); + } + public String getOpinion() { + return StringUtil.get(opinion,"暂无审核意见"); + } + + public void setOpinion(String opinion) { + this.opinion = opinion; + } + + public String getAuditTime() { + return StringUtil.get(auditTime,"暂无"); + } + + public void setAuditTime(String auditTime) { + this.auditTime = auditTime; + } + + public String getAuditUserTypeStr() { + if (auditUserType == null) return "暂无:"; + switch (auditUserType){ + case "2": + return "所在单位意见:"; + case "3": + return "所在地市意见:"; + case "6": + return "省厅意见:"; + default: + return "运维单位:"; + } + } + + public String getAuditUserType() { + return auditUserType; + } + + public void setAuditUserType(String auditUserType) { + this.auditUserType = auditUserType; + } + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/ApplyBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/ApplyBean.java new file mode 100644 index 0000000..5202526 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/ApplyBean.java @@ -0,0 +1,318 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ycgis.macall.personalcenter.R; + +/** + * created by: Macall + * create time: 2023/6/2 11:07 + * copyright: @ruansee.com + * Describe: 应用申请 + */ +public class ApplyBean extends BaseBean { + private String id; + private String name; + private String code; + private String userId; + private String sysName; + private String sysId; + private String roleName; + private int type; + private String time; + private String phone; + private String applyReason; + + private String reviewComments; + + private String node; + + private boolean isSel = false; + //多选 + private boolean isMore = false; + + /** + * 状态码 + * 10 默认普通新增未审核 11 单位审核通过 12 单位审核不通过 + * 20 市局直属新增未审核 21 市局审核通过 22 市局审核不通过 + * 30 省厅直属新增未审核 31 省厅审核通过 32 省厅审核不通过 + * 1 完成 + * 0 删除 + */ + private int state; + private String deptCode; + private String deptName; + private String idCordNum; + + public String getSysId() { + return sysId; + } + + public void setSysId(String sysId) { + this.sysId = sysId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getApplyReason() { + return StringUtil.get(applyReason,"暂无"); + } + + public void setApplyReason(String applyReason) { + this.applyReason = applyReason; + } + + public String getReviewComments() { + return reviewComments; + } + + public void setReviewComments(String reviewComments) { + this.reviewComments = reviewComments; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getNameStr() { + return String.format(" 申 请 人:%s(%s)", name, code); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getSysName() { + return sysName; + } + + public String getSysNameStr() { + return "系统名称:" + sysName; + } + + public void setSysName(String sysName) { + this.sysName = sysName; + } + + public String getRoleNameStr() { + return "角色名称:" + roleName; + } + + public String getRoleName() { + return roleName; + } + + public void setRoleName(String roleName) { + this.roleName = roleName; + } + + public String getTypeStr() { + String s = type == 1 ? "申请" : "撤销"; + return "操作类型:" + s; + } + public int getType() { + return type; + } + + public String getTypeStr2() { + return type == 1 ? "申请" : "撤销"; + } + + public void setType(int type) { + this.type = type; + } + + public String getTimeStr() { + return "申请时间:" + time; + } + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + public boolean isSel() { + return isSel; + } + + public void setSel(boolean sel) { + isSel = sel; + } + + public boolean isMore() { + return isMore; + } + + public void setMore(boolean more) { + isMore = more; + } + + /** + * 状态码 + * 10 默认普通新增未审核 11 单位审核通过 12 单位审核不通过 + * 20 市局直属新增未审核 21 市局审核通过 22 市局审核不通过 + * 30 省厅直属新增未审核 31 省厅审核通过 32 省厅审核不通过 + * 1 完成 + * 0 删除 + */ + public int stateBG() { + switch (state) { + case 1: + return R.drawable.bk_ls; + case 10: + case 20: + case 30: + case 11: + case 21: + case 31: + default: + return R.drawable.bk_hs; + case 22: + case 32: + case 12: + case 0: + return R.drawable.bk_read; + } + } + + /** + * 状态码 + * 10 默认普通新增未审核 11 单位审核通过 12 单位审核不通过 + * 20 市局直属新增未审核 21 市局审核通过 22 市局审核不通过 + * 30 省厅直属新增未审核 31 省厅审核通过 32 省厅审核不通过 + * 1 完成 + * 0 删除 + */ + public int stateColor() { + switch (state) { + case 1: + return R.color.colorGreen7; + case 10: + case 20: + case 30: + case 11: + case 21: + case 31: + default: + return R.color.colorYellow7; + case 22: + case 32: + case 12: + case 0: + return R.color.colorRed7; + } + } + + /** + * 状态码 + * 10 默认普通新增未审核 11 单位审核通过 12 单位审核不通过 + * 20 市局直属新增未审核 21 市局审核通过 22 市局审核不通过 + * 30 省厅直属新增未审核 31 省厅审核通过 32 省厅审核不通过 + * 1 完成 + * 0 删除 + */ + public String getStateStr() { + switch (state) { + case 0: + return "删除"; + case 1: + return "完成"; + case 10: + case 20: + case 30: + case 11: + case 21: + case 31: + default: + return "待审核"; + case 22: + case 32: + case 12: + return "不通过"; + } + } + + public int getState() { + return state; + } + + public void setState(int state) { + this.state = state; + } + + public String getDeptCode() { + return deptCode; + } + + public void setDeptCode(String deptCode) { + this.deptCode = deptCode; + } + + public String getDeptNameStr() { + return "所属单位:" + deptName; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getIdCordNumStr() { + return "身份证号:" + idCordNum; + } + + public String getIdCordNum() { + return idCordNum; + } + + public void setIdCordNum(String idCordNum) { + this.idCordNum = idCordNum; + } + + public String getNodeStr() { + return "当前节点:" + node; + } + + public String getNode() { + return node; + } + + public void setNode(String node) { + this.node = node; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/AuthManageItem.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/AuthManageItem.java new file mode 100644 index 0000000..55e2478 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/AuthManageItem.java @@ -0,0 +1,83 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +import com.anhui.police.auth.sdk.AuthType; + +public class AuthManageItem extends BaseBean { + + private String name; + // 模式是否绑定 + private boolean autheType; + + // 是否支持修改 + private boolean isUpdate = false; + + //是否开通 + private boolean isActivate = false; + + private AuthType authType; + + //该模式是否被选中 + private boolean isSelect = false; + + // 2 修改密码 + private int type = 1; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public boolean isActivate() { + return isActivate; + } + + public void setActivate(boolean activate) { + isActivate = activate; + } + + public AuthManageItem(String name, boolean autheType, boolean isUpdate, AuthType authType) { + this.name = name; + this.autheType = autheType; + this.isUpdate = isUpdate; + this.authType = authType; + } + + public AuthType getAuthType() { + return authType; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isAutheType() { + return autheType; + } + + public void setAutheType(boolean autheType) { + this.autheType = autheType; + } + + public boolean isUpdate() { + return isUpdate; + } + + public void setUpdate(boolean update) { + isUpdate = update; + } + + public boolean isSelect() { + return isSelect; + } + + public void setSelect(boolean select) { + isSelect = select; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/BaseBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/BaseBean.java new file mode 100644 index 0000000..157944b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/BaseBean.java @@ -0,0 +1,29 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +/** + * created by: Macall + * create time: 2022/11/7 17:27 + * copyright: @ruansee.com + * Describe: + */ +public abstract class BaseBean { + protected int baseType; + protected String baseMessage; + + + public int getBaseType() { + return baseType; + } + + public void setBaseType(int baseType) { + this.baseType = baseType; + } + + public String getBaseMessage() { + return baseMessage; + } + + public void setBaseMessage(String baseMessage) { + this.baseMessage = baseMessage; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/FeedbackBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/FeedbackBean.java new file mode 100644 index 0000000..ab62fb0 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/FeedbackBean.java @@ -0,0 +1,148 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +import com.rs.macall.androidx.basemodel.utils.StringUtil; + +import java.io.Serializable; + +/** + * created by: Macall + * create time: 2023/11/16 15:29 + * copyright: @ruansee.com + * Describe: + */ +public class FeedbackBean extends BaseBean implements Serializable { + + /** + * id : 5 + * applicationId : 23 + * alarmSignal : 064922 + * alarmName : 陈乐 + * type : 1 + * createTime : 2023-11-16 14:49:54 + * title : APP测试 + * content : 看看效果 + * applicationName : 聆听通讯 + * updateTime : null + */ + + private int id; + private int type; + private String createTime; + private String title; + private String content; + private String applicationName; + private int replyStatus; + private String replyContent; + private String replier; + private String updateTime; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getType() { + return type; + } + + public String getTypeStr() { + switch (type) { + case 1: + return "个人建议"; + case 2: + return "软件问题"; + case 3: + return "硬件问题"; + default: + case 4: + return "其它"; + } + } + + public void setType(int type) { + this.type = type; + } + + public String getCreateTime() { + return createTime; + } + + public String getCreateTimeStr() { + return StringUtil.get(createTime, "暂无"); + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public int getReplyStatus() { + return replyStatus; + } + + public String getReplyStatusStr() { + return replyStatus == 0?"未回复":"已回复"; + } + + public void setReplyStatus(int replyStatus) { + this.replyStatus = replyStatus; + } + + public String getTitle() { + return title; + } + + public String getTitleStr() { + return StringUtil.get(title, "暂无"); + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public String getContentStr() { + return StringUtil.get(content, "暂无"); + } + + public void setContent(String content) { + this.content = content; + } + + public String getApplicationName() { + return applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + public String getReplyContent() { + return StringUtil.get(replyContent,"暂无"); + } + + public void setReplyContent(String replyContent) { + this.replyContent = replyContent; + } + + public String getReplier() { + return StringUtil.get(replier,"暂无"); + } + + public void setReplier(String replier) { + this.replier = replier; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/FrequentlyItemBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/FrequentlyItemBean.java new file mode 100644 index 0000000..473b946 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/FrequentlyItemBean.java @@ -0,0 +1,55 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +import com.rs.macall.androidx.basemodel.utils.StringUtil; + +import java.io.Serializable; + +/** + * created by: Macall + * create time: 2023/11/7 14:48 + * copyright: @ruansee.com + * Describe: + */ +public class FrequentlyItemBean extends BaseBean implements Serializable { + /** + * problem : 1、应用中心下载后安装失败? + * reply : 如果安装包已经下载且点击安装后安装不了的,返回应用中心’首页‘,切换到‘应用管理’,至’安装包管理‘,找到并删除已下载的安装包,然后返回’首页‘重新下载安装应用。如果此操作还是安装不了,建议电话联系应用中心运维人员反馈 + * extend : 查找应用中心运维人员联系方式 + */ + private String problem; + private String reply; + private String extend; + private String guidance; + + public String getProblem() { + return problem; + } + + public void setProblem(String problem) { + this.problem = problem; + } + + public String getReply() { + return StringUtil.get("\t\t"+reply.replace("\\n","\n").replace("\\t","\t"),"暂无"); + } + + public void setReply(String reply) { + this.reply = reply; + } + + public String getExtend() { + return extend; + } + + public void setExtend(String extend) { + this.extend = extend; + } + + public String getGuidance() { + return guidance; + } + + public void setGuidance(String guidance) { + this.guidance = guidance; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/HomeMessageBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/HomeMessageBean.java new file mode 100644 index 0000000..9380ef4 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/HomeMessageBean.java @@ -0,0 +1,39 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/10 10:26 + * copyright: @ruansee.com + * Describe: + */ +public class HomeMessageBean { + private int count; + private String title; + private List messageBeanList; + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public List getMessageBeanList() { + return messageBeanList; + } + + public void setMessageBeanList(List messageBeanList) { + this.messageBeanList = messageBeanList; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/MessageBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/MessageBean.java new file mode 100644 index 0000000..84661c7 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/MessageBean.java @@ -0,0 +1,191 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +import com.rs.macall.androidx.basemodel.utils.StringUtil; + +import java.io.Serializable; + +/** + * created by: Macall + * create time: 2022/11/11 17:17 + * copyright: @ruansee.com + * Describe: + */ +public class MessageBean extends BaseBean implements Serializable { + private String id; + private String msgId; + // private String title; + private String appName; + // private String time; +// private String content; +// private String clientId; + private String msgType; + // private String clientSecret; + private String appIcon; + private String state; + + + /** + * 是否在个人中心APP内展示: + * 0 :跳转第三方应用内展示 + * 1 : 直接在个人中心展示 + * 默认值0 + */ + private int appExhibition = 0; + + + /** + * ture 已读 false 未读 + */ + private boolean isRead = false; +// private String appLinkUrl; + + private int drawable; + + private String applicationId; + /** + * msgTitle : 危险性评估到期 + * msgContent : 您有一条关于刘双胜(340823198612214011)危险性评估任务即将到期,请及时进行危估 + * userId : 999013 + * state : 0 + * appId : 9450172311301425102 + * appSecret : B5479QP8p2I216B3M9gNpL363Z77dM8S + * sendingTime : 2023-01-05 17:40:38 + * readingTime : null + * appUrl : cbh + */ + + private String msgTitle; + private String msgContent; + private String appId; + private String appSecret; + private String sendingTime; + private String appUrl; + + public int getAppExhibition() { + return appExhibition; + } + + public void setAppExhibition(int appExhibition) { + this.appExhibition = appExhibition; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getAppIcon() { + return appIcon; + } + + public void setAppIcon(String appIcon) { + this.appIcon = appIcon; + } + + public int getDrawable() { + return drawable; + } + + public void setDrawable(int drawable) { + this.drawable = drawable; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getMsgId() { + return msgId; + } + + public void setMsgId(String msgId) { + this.msgId = msgId; + } + + public String getTitle() { + return msgTitle; + } + + public void setTitle(String title) { + this.msgTitle = title; + } + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + } + + public String getTime() { + return sendingTime; + } + + public void setTime(String time) { + this.sendingTime = time; + } + + public String getContent() { + return "\t" + StringUtil.get(msgContent, "暂无"); + } + + public void setContent(String content) { + this.msgContent = content; + } + + public boolean isRead() { + return isRead; + } + + public void setRead(boolean read) { + isRead = read; + } + + public String getAppLinkUrl() { + return appUrl; + } + + public void setAppLinkUrl(String appLinkUrl) { + this.appUrl = appLinkUrl; + } + + public String getClientId() { + return appId; + } + + public void setClientId(String clientId) { + this.appId = clientId; + } + + public String getClientSecret() { + return appSecret; + } + + public void setClientSecret(String clientSecret) { + this.appSecret = clientSecret; + } + + public String getMsgType() { + return msgType; + } + + public void setMsgType(String msgType) { + this.msgType = msgType; + } + + public String getApplicationId() { + return applicationId; + } + + public void setApplicationId(String applicationId) { + this.applicationId = applicationId; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/MyItem.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/MyItem.java new file mode 100644 index 0000000..20a89cd --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/MyItem.java @@ -0,0 +1,39 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; + +/** + * created by: Macall + * create time: 2022/11/10 10:28 + * copyright: @ruansee.com + * Describe: + */ +public class MyItem extends BaseBean { + private String title; + private int icon; + private Class activityClass; + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public int getIcon() { + return icon; + } + + public void setIcon(int icon) { + this.icon = icon; + } + + public Class getActivityClass() { + return activityClass; + } + + public void setActivityClass(Class activityClass) { + this.activityClass = activityClass; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/OrgBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/OrgBean.java new file mode 100644 index 0000000..e99a115 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/OrgBean.java @@ -0,0 +1,42 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +public class OrgBean extends BaseBean{ + private String deptName; + private String deptId; + + private int type = 1; // 1 列表 -1 错误 -2 未查询到结果 + + private boolean isSelect = false; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getOrgName() { + return deptName; + } + + public void setOrgName(String orgName) { + this.deptName = orgName; + } + + public String getOrgCode() { + return deptId; + } + + public void setOrgCode(String orgCode) { + this.deptId = orgCode; + } + + public boolean isSelect() { + return isSelect; + } + + public void setSelect(boolean select) { + isSelect = select; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/SelectAddressBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/SelectAddressBean.java new file mode 100644 index 0000000..b9a7d17 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/SelectAddressBean.java @@ -0,0 +1,37 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +/** + * created by: Macall + * create time: 2022/11/14 18:20 + * copyright: @ruansee.com + * Describe: + */ +public class SelectAddressBean { + private String name; + private String code; + private boolean isSelect; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isSelect() { + return isSelect; + } + + public void setSelect(boolean select) { + isSelect = select; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/SelectAppBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/SelectAppBean.java new file mode 100644 index 0000000..1653051 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/SelectAppBean.java @@ -0,0 +1,59 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +/** + * created by: Macall + * create time: 2022/11/19 15:58 + * copyright: @ruansee.com + * Describe: + */ +public class SelectAppBean extends BaseBean{ + private String id; + + private String appName; + + private boolean isSelect = false; + + private Integer icon; + + private String iconUrl; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Integer getIcon() { + return icon; + } + + public void setIcon(Integer icon) { + this.icon = icon; + } + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + } + + public boolean isSelect() { + return isSelect; + } + + public void setSelect(boolean select) { + isSelect = select; + } + + public String getIconUrl() { + return iconUrl; + } + + public void setIconUrl(String iconUrl) { + this.iconUrl = iconUrl; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/SelectRoleBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/SelectRoleBean.java new file mode 100644 index 0000000..bacf80d --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/SelectRoleBean.java @@ -0,0 +1,64 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +/** + * created by: Macall + * create time: 2023/6/1 16:41 + * copyright: @ruansee.com + * Describe: + */ +public class SelectRoleBean extends BaseBean{ + private String id; + private String appId; + private String appName; + private String name; + private String label; + private boolean isSelect = false; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public boolean isSelect() { + return isSelect; + } + + public void setSelect(boolean select) { + isSelect = select; + } + + public String getAppId() { + return appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/TravelCityBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/TravelCityBean.java new file mode 100644 index 0000000..aefbbb3 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/TravelCityBean.java @@ -0,0 +1,28 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +/** + * created by: Macall + * create time: 2023/11/13 10:30 + * copyright: @ruansee.com + * Describe: + */ +public class TravelCityBean extends BaseBean{ + private String id; + private String name; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/WorkAppBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/WorkAppBean.java new file mode 100644 index 0000000..c5860bf --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/adapterbean/WorkAppBean.java @@ -0,0 +1,85 @@ +package com.ycgis.macall.personalcenter.m.adapterbean; + +import android.graphics.drawable.Drawable; +import android.view.View; + +/** + * created by: Macall + * create time: 2023/11/2 17:38 + * copyright: @ruansee.com + * Describe: + */ +public class WorkAppBean extends BaseBean{ + + private String appName; + private String iconUrl; + private int icon; + private String packageName; + private Drawable applicationIcon; + + private boolean isAdd = false; + + public int isAddStatus(){ + if (!isAdd){ + return View.VISIBLE; + }else { + return View.GONE; + } + } + + public int isDeleteStatus(){ + if (isAdd){ + return View.VISIBLE; + }else { + return View.GONE; + } + } + + public Drawable getApplicationIcon() { + return applicationIcon; + } + + public void setApplicationIcon(Drawable applicationIcon) { + this.applicationIcon = applicationIcon; + } + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + } + + public String getIconUrl() { + return iconUrl; + } + + public void setIconUrl(String iconUrl) { + this.iconUrl = iconUrl; + } + + public int getIcon() { + return icon; + } + + public void setIcon(int icon) { + this.icon = icon; + } + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public boolean isAdd() { + return isAdd; + } + + public void setAdd(boolean add) { + isAdd = add; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/enumbean/AppOpenType.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/enumbean/AppOpenType.java new file mode 100644 index 0000000..953bcda --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/enumbean/AppOpenType.java @@ -0,0 +1,21 @@ +package com.ycgis.macall.personalcenter.m.enumbean; + +/** + * created by: Macall + * create time: 2023/1/30 15:35 + * copyright: @ruansee.com + * Describe: + */ +public enum AppOpenType { + LOGIN("登录"),READ_MESSAGE("查看消息"),SEARCH("搜索内容"); + + private String name; + + AppOpenType(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/event/MessageEvent.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/event/MessageEvent.java new file mode 100644 index 0000000..c121b7b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/event/MessageEvent.java @@ -0,0 +1,41 @@ +package com.ycgis.macall.personalcenter.m.event; + +import com.ycgis.macall.personalcenter.m.adapterbean.MessageBean; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/12/6 15:07 + * copyright: @ruansee.com + * Describe: + */ +public class MessageEvent { + private int count; + private String msg; + private List messageBeanList; + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public List getMessageBeanList() { + return messageBeanList; + } + + public void setMessageBeanList(List messageBeanList) { + this.messageBeanList = messageBeanList; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/model/SelectFileOptions.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/model/SelectFileOptions.java new file mode 100644 index 0000000..2240a70 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/model/SelectFileOptions.java @@ -0,0 +1,91 @@ +package com.ycgis.macall.personalcenter.m.model; + +/** + * created by: Macall + * create time: 2022/11/21 18:16 + * copyright: @ruansee.com + * Describe: H5文件选择配置 + */ +public class SelectFileOptions { + /*是否支持相机拍照*/ + private boolean isCamera; + /*是否支持相册选择*/ + private boolean isDCIM; + /*是否支持文件选择*/ + private boolean isFileSelection; + /*是否由H5自己实现*/ + private boolean selfRealization; + + public SelectFileOptions(boolean isCamera) { + this.isCamera = isCamera; + } + + public SelectFileOptions(boolean isDCIM, boolean isFileSelection) { + this.isDCIM = isDCIM; + this.isFileSelection = isFileSelection; + } + + public SelectFileOptions(boolean selfRealization, boolean isCamera, boolean isDCIM, boolean isFileSelection) { + this.selfRealization = selfRealization; + this.isCamera = isCamera; + this.isDCIM = isDCIM; + this.isFileSelection = isFileSelection; + } + public void configureOptions(boolean selfRealization,boolean isCamera, boolean isDCIM, boolean isFileSelection) { + this.selfRealization = selfRealization; + this.isCamera = isCamera; + this.isDCIM = isDCIM; + this.isFileSelection = isFileSelection; + } + + public boolean isCamera() { + return isCamera; + } + + public void setCamera(boolean camera) { + isCamera = camera; + } + + public boolean isDCIM() { + return isDCIM; + } + + public void setDCIM(boolean DCIM) { + isDCIM = DCIM; + } + + public boolean isFileSelection() { + return isFileSelection; + } + + public void setFileSelection(boolean fileSelection) { + isFileSelection = fileSelection; + } + + public boolean isSelfRealization() { + return selfRealization; + } + + public void setSelfRealization(boolean selfRealization) { + this.selfRealization = selfRealization; + } + + /** + * 是否只配置了一个选项 + * @return true 只配置了一个选项 + * false 配置了多个选项 + */ + public boolean onlyOneItemIsSelected(){ + int count = 0; + if (isCamera){ + count++; + } + if (isDCIM){ + count++; + } + if (isFileSelection){ + count++; + } + return count==1; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/provider/MyFileProvider.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/provider/MyFileProvider.java new file mode 100644 index 0000000..69d803d --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/provider/MyFileProvider.java @@ -0,0 +1,6 @@ +package com.ycgis.macall.personalcenter.m.provider; + +import androidx.core.content.FileProvider; + +public class MyFileProvider extends FileProvider { +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/provider/NativeAppProvider.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/provider/NativeAppProvider.java new file mode 100644 index 0000000..3ea988a --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/provider/NativeAppProvider.java @@ -0,0 +1,261 @@ +package com.ycgis.macall.personalcenter.m.provider; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.graphics.drawable.Drawable; +import android.text.TextUtils; + +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ycgis.macall.personalcenter.m.adapterbean.WorkAppBean; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import io.reactivex.Observable; +import io.reactivex.ObservableEmitter; +import io.reactivex.ObservableOnSubscribe; +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; + +/** + * created by: Macall + * create time: 2023/11/3 9:31 + * copyright: @ruansee.com + * Describe: + */ +public class NativeAppProvider { + private static final String CUSTOM_CACHE_APP_LIST = "cacheCustomAppList"; + /** + * 需要过滤的应用名称 + */ + private static final String FILTER_APP_NAME = "陌生号码识别Print Service音频播放phoneservice桌面资源MyOS主题资源基本互动屏保Gestural Navigation BarFileBrowserCell Broadcast Service" + + "系统配置更新计算器CameraExtensionsProxy系统 WLAN 资源Call Log Backup/Restore运营商默认应用软件包安装程序指纹服务System Resources Package图片编辑Live Wallpaper Picker" + + "系统桌面电话服务主题管理服务急救信息SecCamService存储空间管理器系统跟踪配置拨号器关机闹钟LTE Broadcast ManagerGestural Navigation BarQCC-AUTHMGRzpub.resalsCaptivePortalLoginBluetooth MIDI Service" + + "扫一扫双卡管理用户词典智能识屏录音机华为杂志锁屏系统切换系统通话管理通话设置相机ConfigUpdaterFIDO UAF ASMHwIndexSearchObserverService下载内容iConnect隐私空间androidhwext屏幕录制下载管理器" + + "MmsServiceCompanion Device Manager外部存储设备HTML 查看器Huawei Secure IMEHwIntelligentRecSystem打印处理服务默认打印服务图库SmartcardService媒体存储设备HwChrServiceHwNearby" + + "悬浮导航华为服务框架文件管理器通过蓝牙导入HwSynergyhiview设置建议电话和短信日历存储设置存储时钟拨号联系人存储短信浏览器华为手机助手手机管家中兴手机助手华为桌面手机管理主题系统界面通话/信息存储UEInfoCheck"; + + private Context context; + private List selectPackageAppList; + + public NativeAppProvider(Context context, List selectPackageAppList) { + this.context = context; + this.selectPackageAppList = selectPackageAppList; + } + + /** + * 读取本地全部应用列表 + * + * @return List + */ + public List checkInstallApps() { + List launcherIconPackageList = new ArrayList<>(); + PackageManager pm = context.getPackageManager(); + Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); + mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); + try { + List packageInfos = pm.getInstalledPackages(0); + for (int i = 0; i < packageInfos.size(); i++) { + PackageInfo pkgInfo = packageInfos.get(i); + ApplicationInfo appInfo = pkgInfo.applicationInfo; + if (TextUtils.equals(context.getPackageName(), pkgInfo.packageName)) continue; + String appName = appInfo.loadLabel(pm).toString(); + if (appName.startsWith("com")) continue; + if (appName.startsWith("org")) continue; + if (appName.startsWith("vendor")) continue; + if (appName.startsWith("framework")) continue; + if (appName.startsWith("huawei.android")) continue; + if (appName.endsWith("中兴版")) continue; + if (appName.endsWith("华为版")) continue; + if (appName.startsWith("Android")) continue; + if (appName.contains("游戏")) continue; + if (appName.contains("Huawei")) continue; + if (appName.contains("浏览器")) continue; + if (appName.contains("音乐")) continue; + if (appName.contains("视频")) continue; + if (FILTER_APP_NAME.contains(appName)) continue; + Drawable applicationIcon = pm.getApplicationIcon(appInfo); + WorkAppBean bean = new WorkAppBean(); + bean.setBaseType(1); + bean.setApplicationIcon(applicationIcon); + bean.setIcon(appInfo.icon); + bean.setPackageName(pkgInfo.packageName); + bean.setAppName(appName); + LogUtils.w("本机应用名称",bean.getAppName()); + if (selectPackageAppList != null && !selectPackageAppList.isEmpty()) { + if (selectPackageAppList.contains(bean.getPackageName())) { + bean.setAdd(true); + } + } + launcherIconPackageList.add(bean); + } + } catch (Exception e) { + e.printStackTrace(); + // + } + return launcherIconPackageList; + } + + + /** + * 获取本地全部应用列表 + * + * @param callback 异步回调 + */ + public void asyncCheckInstallApps(BaseRequestCallback> callback) { + Observable.create(new ObservableOnSubscribe>() { + @Override + public void subscribe(@NotNull ObservableEmitter> emitter) throws Exception { + List launcherIconPackageList = checkInstallApps(); + emitter.onNext(launcherIconPackageList); + emitter.onComplete(); + } + }) + .subscribeOn(Schedulers.io()) + //获得的数据返回主线程去更新界面 + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NotNull Disposable d) { + + } + + @Override + public void onNext(@NotNull List packageInfo) { + callback.onRequestSuccess(packageInfo); + } + + @Override + public void onError(@NotNull Throwable e) { + callback.onRequestFailure(e); + } + + @Override + public void onComplete() { + + } + }); + } + + private static Intent getLaunchIntent(PackageManager pm, String pkg) { + Intent intent = pm.getLaunchIntentForPackage(pkg); + if (intent != null) { + return intent; + } else { + intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + intent.setPackage(pkg); + List apps = pm.queryIntentActivities(intent, 0); + if (apps == null || apps.isEmpty()) { + return null; + } + ResolveInfo ri = apps.iterator().next(); + if (ri == null) { + return null; + } + intent.setComponent(new ComponentName(pkg, ri.activityInfo.name)); + return intent; + } + } + + + /** + * 获取本地全部应用列表 + * + * @param callback 异步回调 + */ + public void getSelCustomAppList(BaseRequestCallback> callback) { + Observable.create((ObservableOnSubscribe>) emitter -> { + List launcherIconPackageList = getSelCustomAppList(); + emitter.onNext(launcherIconPackageList); + emitter.onComplete(); + }) + .subscribeOn(Schedulers.io()) + //获得的数据返回主线程去更新界面 + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NotNull Disposable d) { + + } + + @Override + public void onNext(@NotNull List packageInfos) { + callback.onRequestSuccess(packageInfos); + } + + @Override + public void onError(@NotNull Throwable e) { + callback.onRequestFailure(e); + } + + @Override + public void onComplete() { + + } + }); + } + + /** + * 读取本地全部应用列表 + * + * @return List + */ + public List getSelCustomAppList() { + List launcherIconPackageList = new ArrayList<>(); + PackageManager pm = context.getPackageManager(); + Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); + mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); + try { + List packageInfos = pm.getInstalledPackages(0); + String cacheCustomAppList = RuanseeApplication.getStringValue(CUSTOM_CACHE_APP_LIST); + if (StringUtil.isNullOrEmpty(cacheCustomAppList)) return launcherIconPackageList; + for (int i = 0; i < packageInfos.size(); i++) { + PackageInfo pkgInfo = packageInfos.get(i); + ApplicationInfo appInfo = pkgInfo.applicationInfo; + if (TextUtils.equals(context.getPackageName(), pkgInfo.packageName)) continue; + if (cacheCustomAppList.contains(pkgInfo.packageName)) { + Drawable applicationIcon = pm.getApplicationIcon(appInfo); + WorkAppBean bean = new WorkAppBean(); + bean.setBaseType(1); + bean.setApplicationIcon(applicationIcon); + bean.setIcon(appInfo.icon); + bean.setPackageName(pkgInfo.packageName); + bean.setAppName(appInfo.loadLabel(pm).toString()); + launcherIconPackageList.add(bean); + } + } + } catch (Exception e) { + e.printStackTrace(); + // + } + return launcherIconPackageList; + } + + public static void cacheCustomAppList(boolean isAdd, String packageName) { + String cacheCustomAppList = RuanseeApplication.getStringValue(CUSTOM_CACHE_APP_LIST); + if (isAdd) { + if (StringUtil.isNullOrEmpty(cacheCustomAppList)) { + cacheCustomAppList = packageName; + } else { + if (cacheCustomAppList.contains(packageName)) return; + cacheCustomAppList += ";" + packageName; + } + } else { + cacheCustomAppList = cacheCustomAppList.replace(";" + packageName, "").replace(packageName + ";", ""); + } + RuanseeApplication.saveData(CUSTOM_CACHE_APP_LIST, cacheCustomAppList); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/provider/SPCheckKey.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/provider/SPCheckKey.java new file mode 100644 index 0000000..5dae7b0 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/provider/SPCheckKey.java @@ -0,0 +1,17 @@ +package com.ycgis.macall.personalcenter.m.provider;/* + * 项目名:xayss + * 作者:马超 + * 类目:SPCheckKey.java + * 包名:com.ruansee.sx.xayss.m.provider.SPCheckKey + * 当前修改时间:2023年06月16日 11:35:22 + * 上次修改时间:2023年06月16日 11:35:22 + * Copyright©:2023 安徽软思信息技术有限公司 + * 功能描述: + */ + +public final class SPCheckKey { + public static final String CHECK_ARCHIVE_CAR_DATA = "checkArchiveCarData"; + public static final String CACHE_ARCHIVE_CAR_DATA_TIME = "cacheArchiveCarDataTime"; + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/AppInfoModel.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/AppInfoModel.java new file mode 100644 index 0000000..0fb6fc4 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/AppInfoModel.java @@ -0,0 +1,70 @@ +package com.ycgis.macall.personalcenter.m.requestbean; + +import com.ycgis.macall.personalcenter.m.adapterbean.AppInfoBean; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/14 17:00 + * copyright: @ruansee.com + * Describe: + */ +public class AppInfoModel implements Serializable { + + /** + * counts : 7 + * pagesize : 20 + * pages : 1 + * page : 1 + * items : [{"id":21,"name":"皖警云核查","icon":"/profile/upload/2023/01/02/icon_云核查_20230102194657A007.png","link":null,"packageName":"com.ycgis.macall.provinceproject","effectiveness":1,"level":3,"classification":null,"type":1,"sort":1,"cityNumber":null,"serviceProvider":"安徽软思信息技术有限公司","operationPerson":"陈乐","phoneNumber":"15655166626","clientId":"6772242211161756101","clientSecret":"82I8I280VX3PCqNqV886y739S2u86i5B","state":"1","remark":null,"applicant":"管理员","alarmSignal":"admin","department":"安徽省公安厅","applicationTime":"2022-11-16 17:56:23","policeDirector":"沙海峰","policeDirectorSignal":"006856","policePhoneNumber":"15566551515","operationGuide":null,"approvalTime":"2022-11-16 17:56:37","rejectReason":null,"approver":null,"isRecommend":0,"clickCount":7,"label":null,"attribution":0}] + */ + + private int counts; + private int pagesize; + private int pages; + private int page; + private List items; + + public int getCounts() { + return counts; + } + + public void setCounts(int counts) { + this.counts = counts; + } + + public int getPagesize() { + return pagesize; + } + + public void setPagesize(int pagesize) { + this.pagesize = pagesize; + } + + public int getPages() { + return pages; + } + + public void setPages(int pages) { + this.pages = pages; + } + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + public List getItems() { + return items == null?new ArrayList<>():items; + } + + public void setItems(List items) { + this.items = items; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/BaseRequestModel.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/BaseRequestModel.java new file mode 100644 index 0000000..68d5e37 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/BaseRequestModel.java @@ -0,0 +1,62 @@ +package com.ycgis.macall.personalcenter.m.requestbean; + +import com.google.gson.Gson; + +/** + * created by: Macall + * create time: 2022/10/27 16:56 + * copyright: @ruansee.com + * Describe: + */ +public class BaseRequestModel { + private int code; + private String msg; + private int total; +// private int counts; + private T data; + +// public int getCounts() { +// return counts; +// } +// +// public void setCounts(int counts) { +// this.counts = counts; +// } + + public int getTotal() { + return total; + } + + public void setTotal(int totalCount) { + this.total = totalCount; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + @Override + public String toString() { + return new Gson().toJson(this); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/FrequentlyBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/FrequentlyBean.java new file mode 100644 index 0000000..6645260 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/FrequentlyBean.java @@ -0,0 +1,42 @@ +package com.ycgis.macall.personalcenter.m.requestbean; + +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.m.adapterbean.FrequentlyItemBean; + +import java.io.Serializable; +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/7 14:48 + * copyright: @ruansee.com + * Describe: + */ +public class FrequentlyBean extends BaseBean implements Serializable { + + /** + * title : 应用安装登录问题 + * data : [{"problem":"1、应用中心下载后安装失败?","reply":"如果安装包已经下载且点击安装后安装不了的,返回应用中心\u2019首页\u2018,切换到\u2018应用管理\u2019,至\u2019安装包管理\u2018,找到并删除已下载的安装包,然后返回\u2019首页\u2018重新下载安装应用。如果此操作还是安装不了,建议电话联系应用中心运维人员反馈","extend":"查找应用中心运维人员联系方式"},{"problem":"2、登录应用提示设备未绑定?","reply":"提示设备未绑定的,如果跳转到了登录页,就在登录页输入警号和密码后进行绑定。未跳转登录页的,先打开\u2019应用中心\u2018查看是否能正常打开\u2019应用中心\u2018,如果正常打开,就在应用中心搜索该应用,找到运维人员联系方式进行反馈,未正常打开且不跳转登录页的联系市局科信(下发设备的)反馈设备问题。","extend":""}] + */ + + private List data; + + + private String title; + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/GetDeptNameResult.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/GetDeptNameResult.java new file mode 100644 index 0000000..c5e81c6 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/GetDeptNameResult.java @@ -0,0 +1,21 @@ +package com.ycgis.macall.personalcenter.m.requestbean; + +import com.rs.macall.androidx.basemodel.utils.StringUtil; + +/** + * created by: Macall + * create time: 2023/6/19 15:09 + * copyright: @ruansee.com + * Describe: + */ +public class GetDeptNameResult { + private String police_role; + + public String getPolice_role() { + return StringUtil.get(police_role,""); + } + + public void setPolice_role(String police_role) { + this.police_role = police_role; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/HomeBannerBean.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/HomeBannerBean.java new file mode 100644 index 0000000..5d6fe66 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/HomeBannerBean.java @@ -0,0 +1,60 @@ +package com.ycgis.macall.personalcenter.m.requestbean; + +import java.io.Serializable; + +/** + * created by: Macall + * create time: 2023/11/9 11:51 + * copyright: @ruansee.com + * Describe: + */ +public class HomeBannerBean implements Serializable, Comparable { + + /** + * id : 5 + * url : /profile/upload/2023/01/02/icon_banner1.png + * sort : 1 + * effectiveness : 1 + * link : null + * remark : null + */ + + private int id; + private String url; + private int sort; + + public HomeBannerBean(int id, String url, int sort) { + this.id = id; + this.url = url; + this.sort = sort; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public int getSort() { + return sort; + } + + public void setSort(int sort) { + this.sort = sort; + } + + @Override + public int compareTo(HomeBannerBean o) { + return sort-o.getSort()>0?1:-1; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/PagingModel.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/PagingModel.java new file mode 100644 index 0000000..cecc48d --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/PagingModel.java @@ -0,0 +1,32 @@ +package com.ycgis.macall.personalcenter.m.requestbean; + +import java.util.ArrayList; +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/16 15:28 + * copyright: @ruansee.com + * Describe: + */ +public class PagingModel { + private int counts; + + private List items; + + public int getCounts() { + return counts; + } + + public void setCounts(int counts) { + this.counts = counts; + } + + public List getItems() { + return items == null?new ArrayList<>():items; + } + + public void setItems(List items) { + this.items = items; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/WorkbenchModel.java b/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/WorkbenchModel.java new file mode 100644 index 0000000..e96cf10 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/m/requestbean/WorkbenchModel.java @@ -0,0 +1,29 @@ +package com.ycgis.macall.personalcenter.m.requestbean; + +/** + * created by: Macall + * create time: 2023/12/5 14:11 + * copyright: @ruansee.com + * Describe: + */ +public class WorkbenchModel { + private AppInfoModel commonApplications; + + private AppInfoModel newestApplications; + + public AppInfoModel getCommonApplications() { + return commonApplications; + } + + public void setCommonApplications(AppInfoModel commonApplications) { + this.commonApplications = commonApplications; + } + + public AppInfoModel getNewestApplications() { + return newestApplications; + } + + public void setNewestApplications(AppInfoModel newestApplications) { + this.newestApplications = newestApplications; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/app/AppCache.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/app/AppCache.java new file mode 100644 index 0000000..39c29f5 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/app/AppCache.java @@ -0,0 +1,223 @@ +package com.ycgis.macall.personalcenter.p.app; + +import com.anhui.police.auth.sdk.AuthType; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ycgis.macall.personalcenter.util.IPAddressUtils; + +/** + * created by: Macall + * create time: 2023/10/27 15:07 + * copyright: @ruansee.com + * Describe: + */ +public class AppCache { + + private static AppCache appCache; + private String BASE_URL = ""; + //http://192.168.0.233/dev-api/profile/upload/2023/01/02/icon_banner1.png + public static final String BASE_IMAGE_URL = "http://20.90.2.2/pcenter_img_out"; +// public static final String BASE_IMAGE_URL = "http://192.168.43.98:3000/prod-api/"; + + private AuthType authType; + private String appToke; + + private String ip; + private String port; + + private String localIp; + + //系统Token + private String system_token; + + //服务总线token + private String access_token; + //应用申请token + private String apply_token; + + //统一认证token + private String token; + + private String userInfo; + + private String imei,imsi; + + + private AppCache() { + + } + + public synchronized static AppCache getAppCacheData() { + if (appCache == null){ + synchronized (AppCache.class){ + if (appCache == null) appCache = new AppCache(); + } + } + return appCache; + } + + + public void setIpAndPort(String ip,String port){ + this.ip = ip; + this.port = port; + } + + public String getBaseUrlPath() { + if (StringUtil.isNullOrEmpty(BASE_URL)){ + BASE_URL = String.format("http://%s:%s/pcenter_app_out/",ip,port); +// BASE_URL = String.format("http://%s:%s/wzt/",ip,port); + } + return BASE_URL; + } + + public String getLocalIp() { + if (StringUtil.isNullOrEmpty(localIp)){ + localIp = IPAddressUtils.getLocalIpAddress(); + } + return localIp; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getPort() { + return port; + } + + public void setPort(String port) { + this.port = port; + } + + public String getSystem_token() { + return system_token; + } + + public void setSystem_token(String system_token) { + this.system_token = system_token; + } + + public String getAccess_token() { + return access_token; + } + + public void setAccess_token(String access_token) { + this.access_token = access_token; + } + + public String getApply_token() { + return apply_token; + } + + public void setApply_token(String apply_token) { + this.apply_token = apply_token; + } + + public String getToken() { + return StringUtil.get(token,""); + } + + public void setToken(String token) { + this.token = token; + } + + public String getUserInfo() { + return userInfo; + } + + public void setUserInfo(String userInfo) { + this.userInfo = userInfo; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getImsi() { + return imsi; + } + + public void setImsi(String imsi) { + this.imsi = imsi; + } + + public String getSysmCode() { + return "11e8f9a0948a43d78f68c6af41c12242"; + } + + public void setAuthType(AuthType authType) { + if (authType == AuthType.PWD){ + RuanseeApplication.saveData("authType",0); + } else if (authType == AuthType.DIGITAL_CERTIFICATE) { + RuanseeApplication.saveData("authType",1); + }else if (authType == AuthType.GESTURE){ + RuanseeApplication.saveData("authType",2); + }else if (authType == AuthType.FACE){ + RuanseeApplication.saveData("authType",3); + }else if (authType == AuthType.VOICE){ + RuanseeApplication.saveData("authType",4); + }else { + RuanseeApplication.saveData("authType",0); + } + this.authType = authType; + RuanseeApplication.saveData("isUpdateAuthType",true); + } + /** + * 0 : 密码 1 数字证书 2:手势 3 : 人脸 4 :语音 + * @param authType 认证方式 + */ + public void setAuthType(int authType) { + RuanseeApplication.saveData("authType",authType); + switch (authType) { + case 0: + this.authType = AuthType.PWD; + break; + case 1: + this.authType = AuthType.DIGITAL_CERTIFICATE; + break; + case 2: + this.authType = AuthType.GESTURE; + break; + case 3: + this.authType = AuthType.FACE; + break; + case 4: + this.authType = AuthType.VOICE; + break; + default: + this.authType = AuthType.PWD; + break; + } + } + + public AuthType getAuthType() { + if (authType == null) { + int i = RuanseeApplication.getIntegerValue("authType"); + switch (i) { + case 1: + authType = AuthType.DIGITAL_CERTIFICATE; + break; + case 2: + authType = AuthType.GESTURE; + break; + case 3: + authType = AuthType.FACE; + break; + case 4: + authType = AuthType.VOICE; + break; + default: + authType = AuthType.PWD; + break; + } + } + return authType; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/app/CrashHandler.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/app/CrashHandler.java new file mode 100644 index 0000000..42e850b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/app/CrashHandler.java @@ -0,0 +1,216 @@ +package com.ycgis.macall.personalcenter.p.app; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.os.Build; +import android.os.Environment; +import android.os.Looper; +import android.util.Log; +import android.widget.Toast; + +import com.ycgis.macall.personalcenter.util.FileUtils; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.lang.Thread.UncaughtExceptionHandler; +import java.lang.reflect.Field; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +public class CrashHandler implements UncaughtExceptionHandler { + + public static final String TAG = "CrashHandler"; + public static String LOG_DIR = FileUtils.FILE_DIR + "cache/log"; + private UncaughtExceptionHandler mDefaultHandler; + + private static CrashHandler INSTANCE = new CrashHandler(); + + private Context mContext; + + private Map infos = new HashMap(); + +// private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); + + private CrashHandler() { + } + + public synchronized static CrashHandler getInstance() { + if (INSTANCE == null){ + synchronized (CrashHandler.class){ + if (INSTANCE == null){ + INSTANCE = new CrashHandler(); + } + } + } + return INSTANCE; + } + + public void init(Context context,String LOG_DIR) { + mContext = context; + mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); + this.LOG_DIR = LOG_DIR; + Thread.setDefaultUncaughtExceptionHandler(this); + } + + @Override + public void uncaughtException(Thread thread, Throwable ex) { + if (!handleException(ex) && mDefaultHandler != null) { + mDefaultHandler.uncaughtException(thread, ex); + } else { + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + Log.e(TAG, "error : ", e); + } + android.os.Process.killProcess(android.os.Process.myPid()); + System.exit(1); + } + } + + private boolean handleException(Throwable ex) { + if (ex == null) { + return false; + } + final Throwable _ex = ex; + new Thread() { + @Override + public void run() { + Looper.prepare(); + Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出" + _ex.getMessage(), Toast.LENGTH_LONG) + .show(); +// TwitterApplication.LogOut(mContext); + Looper.loop(); + } + }.start(); + + // 收集设备参数信息 + collectDeviceInfo(mContext); + // 保存日志文件 + saveCrashInfo2File(ex); + return true; + } + + /** + * 收集设备参数信息 + * + * @param ctx + */ + public void collectDeviceInfo(Context ctx) { + try { + PackageManager pm = ctx.getPackageManager(); + PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), + PackageManager.GET_ACTIVITIES); + if (pi != null) { + String versionName = pi.versionName == null ? "null" + : pi.versionName; + String versionCode = pi.versionCode + ""; + infos.put("versionName", versionName); + infos.put("versionCode", versionCode); + } + } catch (NameNotFoundException e) { + Log.e(TAG, "an error occured when collect package info", e); + infos.put("Exception1:", "收集系统参数报错"); + } + Field[] fields = Build.class.getDeclaredFields(); + for (Field field : fields) { + try { + field.setAccessible(true); + infos.put(field.getName(), field.get(null).toString()); + Log.d(TAG, field.getName() + " : " + field.get(null)); + } catch (Exception e) { + Log.e(TAG, "an error occured when collect crash info", e); + infos.put("Exception2:", "收集系统参数报错"); + } + } + } + + private void saveCrashInfo2File(Throwable ex) { + StringBuffer sb = new StringBuffer(); + sb.append("================ 系统信息 ===================" + "\n"); + for (Map.Entry entry : infos.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + sb.append(key + "=" + value + "\n"); + } + sb.append("================ 系统信息 /===================" + "\n"); + sb.append("================ 报错信息 ===================" + "\n"); + Writer writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + Throwable cause = ex.getCause(); + while (cause != null) { + cause.printStackTrace(printWriter); + cause = cause.getCause(); + } + printWriter.close(); + String result = writer.toString(); + sb.append(result); + sb.append("================ 报错信息 ===================" + "\n"); + sendErrorLog(sb.toString()); + try { + long timestamp = System.currentTimeMillis() % 100000; + @SuppressLint("SimpleDateFormat") + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); + String time = sdf.format(new Date()); +// String time = formatter.from(new Date()); + String fileName = "WZT_" + time + "-" + timestamp + ".log"; + if (Environment.getExternalStorageState().equals( + Environment.MEDIA_MOUNTED)) { + String path = LOG_DIR; + File dir = new File(path); + if (!dir.exists()) { + dir.mkdirs(); + } + FileOutputStream fos = new FileOutputStream(path + "/" + fileName); + fos.write(sb.toString().getBytes()); + fos.close(); + } + } catch (Exception e) { + Log.e(TAG, "an error occured while writing file...", e); + } + } + + private void sendErrorLog(String errorText) { +// RequestModel.uploadOperationLog("5","2",errorText); +//// String url = "http://192.168.43.202:8081/ypc/phone/error/saveError"; +// String url = YcgisApplication.getAppCacheData().getApiBaseUrl()+"error/saveError"; +// YcgisApplication +// .componet() +// .environment() +// .apiClient() +// .saveErrorLog(url, YcgisApplication.getAppCacheData().getUserCode(), errorText) +// .subscribeOn(Schedulers.io()) +// .observeOn(Schedulers.io()) +// .subscribe(new Observer() { +// @Override +// public void onSubscribe(Disposable d) { +// Log.w(TAG, "onSubscribe " + d.toString()); +// } +// +// @Override +// public void onNext(JsonObject s) { +// Log.w(TAG, s.toString()); +// } +// +// @Override +// public void onError(Throwable e) { +// Log.e(TAG, "onError " + e.getMessage()); +// } +// +// @Override +// public void onComplete() { +// Log.w(TAG, "onComplete "); +// } +// }); + } + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/app/MyAppGlideModule.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/app/MyAppGlideModule.java new file mode 100644 index 0000000..f0f98ba --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/app/MyAppGlideModule.java @@ -0,0 +1,71 @@ +package com.ycgis.macall.personalcenter.p.app; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.GlideBuilder; +import com.bumptech.glide.Registry; +import com.bumptech.glide.annotation.GlideModule; +import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader; +import com.bumptech.glide.load.DecodeFormat; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.load.engine.cache.DiskLruCacheFactory; +import com.bumptech.glide.load.engine.cache.LruResourceCache; +import com.bumptech.glide.load.model.GlideUrl; +import com.bumptech.glide.module.AppGlideModule; +import com.bumptech.glide.request.RequestOptions; +import com.rs.macall.androidx.basemodel.request.OkHttpUtils; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.util.FileUtils; + +import org.jetbrains.annotations.NotNull; + +import java.io.InputStream; + +/** + * @Author macall + * @Create 2019/12/18 0018 + * @Describe + */ +@GlideModule +public class MyAppGlideModule extends AppGlideModule { + + @Override + public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) { + OkHttpUrlLoader.Factory factory = new OkHttpUrlLoader.Factory(OkHttpUtils.getClient(30,40,60)); + registry.replace(GlideUrl.class, InputStream.class, factory); + } + + @Override + public void applyOptions(Context context, GlideBuilder builder) { + // 设置缓存大小为20mb + int memoryCacheSizeBytes = 1024 * 1024 * 50; // 50mb + // 设置内存缓存大小 + builder.setMemoryCache(new LruResourceCache(1024 * 1024*20)); + // 根据SD卡是否可用选择是在内部缓存还是SD卡缓存 + builder.setDiskCache(new DiskLruCacheFactory(FileUtils.IMAGE_DIR,"cache_glide",memoryCacheSizeBytes)); + builder.setDefaultRequestOptions(new Glide.RequestOptionsFactory() { + @NonNull + @NotNull + @Override + public RequestOptions build() { + return new RequestOptions() + .placeholder(R.drawable.icon_not_data) + .error(R.drawable.ic_load_imag_eerror) + .centerCrop() + .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC) + .format(DecodeFormat.DEFAULT) + .encodeQuality(90); + } + }); + } + + // 针对V4用户可以提升速度 + @Override + public boolean isManifestParsingEnabled() { + return false; + } +} + diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/app/RuanseeApplication.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/app/RuanseeApplication.java new file mode 100644 index 0000000..e38b350 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/app/RuanseeApplication.java @@ -0,0 +1,88 @@ +package com.ycgis.macall.personalcenter.p.app; + +import androidx.core.content.ContextCompat; + +import com.anhui.police.auth.sdk.AuthConfig; +import com.anhui.police.auth.sdk.AuthSDK; +import com.anhui.police.auth.sdk.AuthType; +import com.anhui.police.market.sdk.MarketConfigure; +import com.rs.macall.androidx.basemodel.base.BaseApplication; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.ruansee.macall.unifyservemodulesdk.USMConfigure; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.util.FileUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * created by: Macall + * create time: 2023/10/25 15:00 + * copyright: @ruansee.com + * Describe: + */ +public class RuanseeApplication extends BaseApplication { + public static final boolean isPrintLog = true; + public static final boolean isHFVersion = false; + private static AppCache appCache; + private static UserData userData; + public static boolean isShowIIIAppTitle = false; + + // public static final int RefreshMessageTime = 20000; + public static final int RefreshMessageTime = 2 * 60 * 1000; + + /** + * 查询消息的时间间隔 + */ + public static final int REFRESH_MESSAGE_TIME = 2*1000*60; + + static { + CACHE_FILE_NAME = "newPersonalCenterSP"; + isShowWatermark = true; + } + + @Override + protected void init() { + appCache = AppCache.getAppCacheData(); + userData = UserData.getUserData(); + + FileUtils.initFilePath(getApplication()); + new LogUtils.Builder(FileUtils.LOG_DIR) + .setBorderSwitch(isPrintLog) + .setLogSwitch(isPrintLog) + .setLog2FileSwitch(false); + + //统一服务组件 + USMConfigure.getDefault().init("11811535", "grzx_test_app"); + + List types = new ArrayList<>(); + types.add(appCache.getAuthType()); + AuthConfig config = AuthConfig.builder(); + config.setThemeColor(ContextCompat.getColor(getApplicationContext(), R.color.colorAccent)); + config.setAuthTypes(types); + AuthSDK.init("55b161aefd464849b48986a1073d5622", this, config); +// AuthMarkManager.setShowAuthMark(true); + //应用中心检测更新 + MarketConfigure.init(this, "442eab382e6a49649e3402115bd8837f", MarketConfigure.MarketDeviceType.DEVICE_TYPE_PHONE); + MarketConfigure.setUseMarketDownloadHelper(true); + CrashHandler.getInstance().init(getApplication(),FileUtils.LOG_DIR); + } + + public static AppCache getAppCache() { + return appCache; + } + + public static void setAppCache(AppCache appCache) { + RuanseeApplication.appCache = appCache; + } + + public static UserData getUserData() { + return userData; + } + + public static void setUserData(UserData userData) { + RuanseeApplication.userData = userData; + } + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/app/UserData.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/app/UserData.java new file mode 100644 index 0000000..23c4ff1 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/app/UserData.java @@ -0,0 +1,234 @@ +package com.ycgis.macall.personalcenter.p.app; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.Expose; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.util.IdcardUtils; + +/** + * created by: Macall + * create time: 2023/10/27 15:40 + * copyright: @ruansee.com + * Describe: + */ +public class UserData { + private static UserData userData; + + private String photo; + //角色 + private String police_role; + //职务 + private String police_post; + + //警号姓名 + private String userId; + + //警号姓名 + @Expose(serialize = true) + private String userCode; + + @Expose(serialize = true) + private String userName; + + @Expose(serialize = true) + private String idCardNum; + + //用户所属机构 + @Expose(serialize = true) + private String deptCode; + @Expose(serialize = true) + private String deptName; + + @Expose(serialize = true) + private String ip; + + //所在地市代码 + @Expose(serialize = true) + private String departmentCode; + //所在地市名称 + @Expose(serialize = true) + private String departmentName; + + private String phone1; + private String phone2; + + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + //是否是省厅用户 true == 是省厅用户 || false == 地市用户 + private boolean isStUser; + + public void setPhoto(String photo) { + this.photo = photo; + } + + public String getPhoto() { + return photo; + } + + /** + * 用户是否有效 + * 警号、身份号、组织机构代码 不能为空,否则返回 false + * @return true : false + */ + public boolean isValidOrNot() { + if (StringUtil.isNullOrEmpty(userCode)) return false; + if (StringUtil.isNullOrEmpty(deptCode)) return false; + if (StringUtil.isNullOrEmpty(idCardNum)) return false; + return true; + } + + public String getPhone1() { + return StringUtil.get(phone1,"暂无"); + } + + public void setPhone1(String phone1) { + this.phone1 = phone1; + } + + public String getPhone2() { + return StringUtil.get(phone2,"暂无"); + } + + public void setPhone2(String phone2) { + this.phone2 = phone2; + } + + public String getPolice_post() { + return StringUtil.get(police_post,"暂无"); + } + + public void setPolice_post(String police_post) { + this.police_post = police_post; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public synchronized static UserData getUserData() { + if (userData == null) { + synchronized (UserData.class) { + if (userData == null) userData = new UserData(); + } + } + return userData; + } + + public static void setUserData(UserData userData) { + UserData.userData = userData; + } + + public String getPolice_role() { + return StringUtil.get(police_role,"暂无"); + } + + public void setPolice_role(String police_role) { + this.police_role = police_role; + } + + public String getUserCode() { + return userCode; + } + + public void setUserCode(String userCode) { + this.userCode = userCode; + } + + public String getUserName() { + return StringUtil.get(userName,"暂无"); + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getDeptCode() { + return deptCode; + } + + public void setDeptCode(String deptCode) { + this.deptCode = deptCode; + initStUser(); + } + + public String getDeptName() { + return StringUtil.get(deptName,"暂无"); + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDepartmentCode() { + return departmentCode; + } + + public void setDepartmentCode(String departmentCode) { + this.departmentCode = departmentCode; + } + + public String getDepartmentName() { + return departmentName; + } + + public void setDepartmentName(String departmentName) { + this.departmentName = departmentName; + } + + public String getIdCardNum() { + return StringUtil.get(idCardNum,"暂无"); + } + + public void setIdCardNum(String idCardNum) { + this.idCardNum = idCardNum; + } + + public boolean isStUser() { + return isStUser; + } + + public void setStUser(boolean stUser) { + isStUser = stUser; + } + + public void initStUser() { + if (StringUtil.hasContent(deptCode)) { + if (deptCode.startsWith("3400")) { + isStUser = true; + } + } + } + + public String toJson() { + Gson gson = new GsonBuilder() + .excludeFieldsWithoutExposeAnnotation() + .create(); + return gson.toJson(this); + } + + /** + * 获取错误的头像照片 + * 297548 + */ + public int getErrorPhotoByIdCardNum(){ + if (StringUtil.isNullOrEmpty(idCardNum)) return R.drawable.ic_load_imag_eerror; + String genderByIdCard = IdcardUtils.getGenderByIdCard(idCardNum); + if ("M".equals(genderByIdCard))return R.drawable.icon_police_man; + if ("F".equals(genderByIdCard))return R.drawable.icon_police_woman; + return R.drawable.ic_load_imag_eerror; + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/BaseRequestCallback.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/BaseRequestCallback.java new file mode 100644 index 0000000..02f2c11 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/BaseRequestCallback.java @@ -0,0 +1,51 @@ +package com.ycgis.macall.personalcenter.p.callback; + + +import com.ycgis.macall.personalcenter.p.request.HttpErrorHandler; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Author macall + * @Create 2020/1/7 0007 + * @Describe + */ +public abstract class BaseRequestCallback implements RequestCallback { + /*========================= HttpException 异常 code ==========================*/ + + private List payloads; + + public BaseRequestCallback() { + } + + public BaseRequestCallback(List payloads) { + this.payloads = payloads; + } + + public BaseRequestCallback addPayload(Object o){ + if (payloads==null){ + payloads = new ArrayList<>(); + } + payloads.add(o); + return this; + } + + public List getPayloads() { + return payloads; + } + + @Override + public void onRequestFailure(Throwable e) { + onRequestFailure(HttpErrorHandler.requestHandle(e)); + } + + public abstract void onRequestFailure(String msg); + + @Override + public void onStartRequest() { + + } + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/CarFragmentCallback.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/CarFragmentCallback.java new file mode 100644 index 0000000..89a4f27 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/CarFragmentCallback.java @@ -0,0 +1,17 @@ +package com.ycgis.macall.personalcenter.p.callback; + +/* + * 项目名:xayss + * 作者:马超 + * 类目:FramgmentCallback.java + * 包名:com.ruansee.sx.xayss.p.callback.FramgmentCallback + * 当前修改时间:2023年08月17日 08:31:16 + * 上次修改时间:2023年08月17日 08:31:16 + * Copyright©:2023 安徽软思信息技术有限公司 + * 功能描述: + */ +public interface CarFragmentCallback { + + String[] getTimePeriod(); + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/DataModelCallback.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/DataModelCallback.java new file mode 100644 index 0000000..8e119c3 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/DataModelCallback.java @@ -0,0 +1,16 @@ +package com.ycgis.macall.personalcenter.p.callback;/* + * 项目名:xayss + * 作者:马超 + * 类目:DataModelCallback.java + * 包名:com.ruansee.sx.xayss.p.callback.DataModelCallback + * 当前修改时间:2023年05月22日 15:34:38 + * 上次修改时间:2023年05月22日 15:34:38 + * Copyright©:2023 安徽软思信息技术有限公司 + * 功能描述: + */ + +public interface DataModelCallback { + + void onUpdate(int what,int org,Object obg); + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/DerivativeCallback.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/DerivativeCallback.java new file mode 100644 index 0000000..29730b1 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/DerivativeCallback.java @@ -0,0 +1,16 @@ +package com.ycgis.macall.personalcenter.p.callback; + +import android.view.View; + +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; + + +/** + * created by: Macall + * create time: 2023/3/27 16:50 + * copyright: @ruansee.com + * Describe: + */ +public interface DerivativeCallback { + void onItemClick(View view, BaseBean baseBean, int position); +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/EditTextWatcherListener.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/EditTextWatcherListener.java new file mode 100644 index 0000000..5a6d9b0 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/EditTextWatcherListener.java @@ -0,0 +1,56 @@ +package com.ycgis.macall.personalcenter.p.callback;/* + * 项目名:xayss + * 作者:马超 + * 类目:EditTextWatcherListener.java + * 包名:com.ruansee.sx.xayss.p.callback.EditTextWatcherListener + * 当前修改时间:2023年05月08日 14:26:02 + * 上次修改时间:2023年05月08日 14:26:02 + * Copyright©:2023 安徽软思信息技术有限公司 + * 功能描述: + */ + +import android.text.Editable; +import android.text.Spannable; +import android.text.TextWatcher; + +public abstract class EditTextWatcherListener implements TextWatcher { + /** + * This method is called to notify you that, within s, + * the count characters beginning at start + * are about to be replaced by new text with length after. + * It is an error to attempt to make changes to s from + * this callback. + */ + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + /** + * This method is called to notify you that, within s, + * the count characters beginning at start + * have just replaced old text that had length before. + * It is an error to attempt to make changes to s from + * this callback. + */ + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + /** + * This method is called to notify you that, somewhere within + * s, the text has been changed. + * It is legitimate to make further changes to s from + * this callback, but be careful not to get yourself into an infinite + * loop, because any changes you make will cause this method to be + * called again recursively. + * (You are not told where the change took place because other + * afterTextChanged() methods may already have made other changes + * and invalidated the offsets. But if you need to know here, + * you can use {@link Spannable#setSpan} in {@link #onTextChanged} + * to mark your place and then look up from here where the span + * ended up. + */ + public void afterTextChanged(Editable s){ + + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/GPSListener.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/GPSListener.java new file mode 100644 index 0000000..be6595f --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/GPSListener.java @@ -0,0 +1,12 @@ +package com.ycgis.macall.personalcenter.p.callback; + +import com.rs.macall.androidx.basemodel.utils.GpsUtil; + +/** + * created by: Macall + * create time: 2023/3/28 9:40 + * copyright: @ruansee.com + * Describe: + */ +public class GPSListener extends GpsUtil { +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/GPSLocationListener.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/GPSLocationListener.java new file mode 100644 index 0000000..abe5c2d --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/GPSLocationListener.java @@ -0,0 +1,51 @@ +package com.ycgis.macall.personalcenter.p.callback; + +import android.location.Location; + +/** + * created by: Macall + * create time: 2023/3/28 9:38 + * copyright: @ruansee.com + * Describe: + */ +public abstract class GPSLocationListener { + + /** + * 位置发生改变 + * @param location + */ + public abstract void onLocationChanged(Location location); + + public void stopLocation(){} + + public void onScanSatellite(int totalCount,int bduCount,int locationCount){} + +// /** +// * 定位状态发生改变 +// * @param provider +// * @param status +// * @param extras +// */ +// @Override +// public void onStatusChanged(String provider, int status, Bundle extras) { +// +// } +// +// /** +// * 启用 定位模式 +// * @param provider +// */ +// @Override +// public void onProviderEnabled(String provider) { +// +// } +// +// /** +// * 定位模式 被禁用 +// * @param provider +// */ +// @Override +// public void onProviderDisabled(String provider) { +// +// } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/ImageCallBack.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/ImageCallBack.java new file mode 100644 index 0000000..2541082 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/ImageCallBack.java @@ -0,0 +1,16 @@ +package com.ycgis.macall.personalcenter.p.callback; + +import android.graphics.Bitmap; +import android.widget.ImageView; + +/** + * created by: Macall + * create time: 2023/11/16 9:46 + * copyright: @ruansee.com + * Describe: + */ +public interface ImageCallBack { + public void imageLoad(ImageView imageView, Bitmap bitmap); + + public void imageLoadError(ImageView imageView, String message); +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/MainSearchRequestCallback.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/MainSearchRequestCallback.java new file mode 100644 index 0000000..e4ffc43 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/MainSearchRequestCallback.java @@ -0,0 +1,43 @@ +package com.ycgis.macall.personalcenter.p.callback; + +import com.ycgis.macall.personalcenter.p.request.HttpErrorHandler; + +/* + * 项目名:xayss + * 作者:马超 + * 类目:MainSearchRequestCallback.java + * 包名:com.ruansee.sx.xayss.p.callback.MainSearchRequestCallback + * 当前修改时间:2023年07月28日 15:30:09 + * 上次修改时间:2023年07月28日 15:30:09 + * Copyright©:2023 安徽软思信息技术有限公司 + * 功能描述: + */ +public abstract class MainSearchRequestCallback extends BaseRequestCallback { + /*========================= HttpException 异常 code ==========================*/ + private String paramKey; + private Class eClass; + + public MainSearchRequestCallback(String paramKey, Class eClass) { + this.paramKey = paramKey; + this.eClass = eClass; + } + + abstract public void onRequestSuccess(T result,String paramKey,Class eClass); + + @Override + public void onRequestSuccess(T result) { + onRequestSuccess(result,paramKey,eClass); + } + + @Override + public void onRequestFailure(Throwable e) { + onRequestFailure(HttpErrorHandler.requestHandle(e)); + } + + public abstract void onRequestFailure(String msg); + + @Override + public void onStartRequest() { + + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/OnAdapterLongClickListener.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/OnAdapterLongClickListener.java new file mode 100644 index 0000000..c5d13e8 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/OnAdapterLongClickListener.java @@ -0,0 +1,34 @@ +package com.ycgis.macall.personalcenter.p.callback; + +import android.view.View; + +/** + * created by: Macall + * create time: 2023/10/13 16:30 + * copyright: @ruansee.com + * Describe: + */ +abstract public class OnAdapterLongClickListener implements View.OnLongClickListener { + + private E data; + private int position; + + public OnAdapterLongClickListener(E data, int position) { + this.data = data; + this.position = position; + } + + + public void setParam(E data, int position) { + this.data = data; + this.position = position; + } + + @Override + public boolean onLongClick(View v) { + onLongClick(v,data,position); + return true; + } + + protected abstract void onLongClick(View v, E data, int position); +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/OnFragmentOnClickListener.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/OnFragmentOnClickListener.java new file mode 100644 index 0000000..91ba0ce --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/OnFragmentOnClickListener.java @@ -0,0 +1,14 @@ +package com.ycgis.macall.personalcenter.p.callback; + +import android.view.View; + +import org.jetbrains.annotations.NotNull; + +public interface OnFragmentOnClickListener { + + @NotNull + void onClickListener(View view,@NotNull Object obj); + + @NotNull + void ovReturnData(String json); +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/OnGlobalLayoutListenerByEllipsize.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/OnGlobalLayoutListenerByEllipsize.java new file mode 100644 index 0000000..cb9d91a --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/OnGlobalLayoutListenerByEllipsize.java @@ -0,0 +1,54 @@ +package com.ycgis.macall.personalcenter.p.callback; + +import android.text.TextUtils; +import android.view.ViewTreeObserver; +import android.widget.TextView; + +/** + * created by: Macall + * create time: 2023/8/23 10:05 + * copyright: @ruansee.com + * Describe: + */ +public class OnGlobalLayoutListenerByEllipsize implements ViewTreeObserver.OnGlobalLayoutListener { + + private TextView mTextView; + private int mMaxLines; //最大行数 + + public OnGlobalLayoutListenerByEllipsize(TextView textView, int maxLines){ + if(maxLines <= 0) + throw new IllegalArgumentException("maxLines不能小于等于0"); + this.mTextView = textView; + this.mMaxLines = maxLines; + this.mTextView.setMaxLines(mMaxLines+1); + this.mTextView.setSingleLine(false); + } + + @Override + public void onGlobalLayout() { + if(mTextView.getLineCount() > mMaxLines){ + int line = mTextView.getLayout().getLineEnd(mMaxLines-1); + CharSequence truncate = "...";//定义成CharSequence类型,是为了兼容emoji表情,如果使用String类型则会造成emoji无法显示 + CharSequence text = mTextView.getText(); + try { + text = text.subSequence(0, line - 3); + }catch (Exception e){ + truncate = ""; + text = mTextView.getText(); + } + TextUtils.TruncateAt at = mTextView.getEllipsize(); + if(at == TextUtils.TruncateAt.START) { + mTextView.setText(truncate); + mTextView.append(text); + }else if(at == TextUtils.TruncateAt.MIDDLE){ + mTextView.setText(text.subSequence(0,text.length()/2)); + mTextView.append(truncate); + mTextView.append(text.subSequence(text.length()/2,text.length())); + }else { + mTextView.setText(text); + mTextView.append(truncate); + } + } + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/RequestCallback.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/RequestCallback.java new file mode 100644 index 0000000..2f23d5f --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/RequestCallback.java @@ -0,0 +1,16 @@ +package com.ycgis.macall.personalcenter.p.callback; + +/** + * @Author macall + * @Create 2020/1/7 0007 + * @Describe + */ +public interface RequestCallback { + void onStartRequest(); + + /*成功*/ + void onRequestSuccess(T result); + + /*失败*/ + void onRequestFailure(Throwable e); +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/SelectReturnCallback.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/SelectReturnCallback.java new file mode 100644 index 0000000..aaa545b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/SelectReturnCallback.java @@ -0,0 +1,12 @@ +package com.ycgis.macall.personalcenter.p.callback; + +/** + * created by: Macall + * create time: 2022/11/15 15:40 + * copyright: @ruansee.com + * Describe: + */ +public interface SelectReturnCallback { + + void returnMsg(T message); +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/UploadProgressListener.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/UploadProgressListener.java new file mode 100644 index 0000000..469d51d --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/UploadProgressListener.java @@ -0,0 +1,17 @@ +package com.ycgis.macall.personalcenter.p.callback; + +/** + * Created by macall on 2018-06-06. + * copyright:ycgis + */ + +public interface UploadProgressListener { + void onUploadProgress(long totalBytes, long remainingBytes, boolean done); + + /** + * 完成状态 + * + * @param totalSize + */ + public void onUploadDone(long totalSize); +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/WebActivityCallback.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/WebActivityCallback.java new file mode 100644 index 0000000..f56011b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/WebActivityCallback.java @@ -0,0 +1,16 @@ +package com.ycgis.macall.personalcenter.p.callback; + +import com.rs.macall.androidx.basemodel.callback.BasePresenterCallback; + +/** + * created by: Macall + * create time: 2022/11/21 17:30 + * copyright: @ruansee.com + * Describe: + */ +public interface WebActivityCallback extends BasePresenterCallback { + + void onShowOperationSelectDialog( String[] split ,int whit); + + void onFinish(); +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/WorkManageCallback.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/WorkManageCallback.java new file mode 100644 index 0000000..554f07b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/callback/WorkManageCallback.java @@ -0,0 +1,14 @@ +package com.ycgis.macall.personalcenter.p.callback; + +import com.ycgis.macall.personalcenter.m.adapterbean.WorkAppBean; + +/** + * created by: Macall + * create time: 2023/11/3 11:12 + * copyright: @ruansee.com + * Describe: + */ +public interface WorkManageCallback { + void onAdd(WorkAppBean appBean); + void onRemove(WorkAppBean appBean); +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/presenter/BasePresenter.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/presenter/BasePresenter.java new file mode 100644 index 0000000..d7a285c --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/presenter/BasePresenter.java @@ -0,0 +1,59 @@ +package com.ycgis.macall.personalcenter.p.presenter; + +import android.content.Context; + +import com.rs.macall.androidx.basemodel.callback.BasePresenterCallback; +import com.rs.macall.androidx.basemodel.utils.ProgressDialogUtils; + + +/** + * @Author macall + * @Create 2019/12/4 0004 + * @Describe + */ +public abstract class BasePresenter { + protected static String TAG = ""; + protected Context context; + protected T callBack; + + private ProgressDialogUtils dialogUtils; + + public BasePresenter(Context context, T callback){ + this.context = context; + this.callBack = callback; + TAG = getClass().getSimpleName(); + } + + public Context getContext() { + return context; + } + + public void baseShowDialog(String mess) { + baseShowDialog("提示信息", mess); + } + + public void baseShowDialog(String title, String mess) { + if (dialogUtils == null) dialogUtils = new ProgressDialogUtils(context); + else dialogUtils.dismiss(); + dialogUtils.show(title, mess); + } + + public void baseShowFaseDialong(String title, String mess) { + if (dialogUtils == null) dialogUtils = new ProgressDialogUtils(context); + else dialogUtils.dismiss(); + dialogUtils.showFase(title, mess); + } + + public void baseDialogUpdateMessage(String mess) { + if (dialogUtils == null) { + baseShowDialog(mess); + } else { + dialogUtils.setMessage(mess); + } + } + + public void baseDismissDialog() { + if (dialogUtils != null) dialogUtils.dismiss(); + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/presenter/WebViewPresenter.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/presenter/WebViewPresenter.java new file mode 100644 index 0000000..ca2ebb7 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/presenter/WebViewPresenter.java @@ -0,0 +1,493 @@ +package com.ycgis.macall.personalcenter.p.presenter; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.DownloadManager; +import android.content.ClipData; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.net.http.SslError; +import android.os.Build; +import android.os.Environment; +import android.provider.MediaStore; +import android.view.LayoutInflater; +import android.view.View; +import android.webkit.JsResult; +import android.webkit.SslErrorHandler; +import android.webkit.URLUtil; +import android.webkit.ValueCallback; +import android.webkit.WebResourceError; +import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; +import android.webkit.WebView; +import android.widget.TextView; + +import com.just.agentweb.WebChromeClient; +import com.just.agentweb.WebViewClient; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.utils.BitMapUtils; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.m.model.SelectFileOptions; +import com.ycgis.macall.personalcenter.p.callback.WebActivityCallback; +import com.ycgis.macall.personalcenter.p.request.DownloadUtil; +import com.ycgis.macall.personalcenter.util.FileUtils; +import com.ycgis.macall.personalcenter.util.UriUtils; + +import java.io.File; + +import top.zibin.luban.OnCompressListener; + +import static android.content.Context.DOWNLOAD_SERVICE; + +/** + * created by: Macall + * create time: 2022/11/21 17:26 + * copyright: @ruansee.com + * Describe: + */ +public class WebViewPresenter extends BasePresenter { + public File photoFile; + public final static int RESULT_CODE = 10000; + public final static int SELECT_IMG_CODE = 10001; + public final static int SELECT_FILE_CODE = 10002; + public SelectFileOptions selectFileOptions; + private String fileTypes; + private Dialog selectItems; + private boolean isLogin = false; + public String ywryName = "", ywryPhone = ""; + + public String intoUrl = "http://20.90.1.150:8888/"; +// public Map selectFileOptionsMap; + + public ValueCallback mFilePathCallback; + + public WebViewPresenter(Context context, WebActivityCallback callback) { + super(context, callback); +// selectFileOptionsMap = new HashMap<>(); + } + + public void onDestroy() { + + } + + /** + * 相机拍照 + * + * @param activity 当前活动 + */ + private void skipPickPhoto(Activity activity) { + if (photoFile != null && photoFile.exists()) { + photoFile.delete(); + } + photoFile = new File(FileUtils.IMAGE_DIR, FileUtils.getPhotoName()); + Intent photoIntent = UriUtils.getPhotoIntent(context, photoFile); + activity.startActivityForResult(photoIntent, RESULT_CODE); + } + + /** + * 根据文件选择配置 实现选择弹框 + */ + private void showSelectUploadDialog() { + if (selectFileOptions.onlyOneItemIsSelected()) { + if (selectFileOptions.isCamera()) { + callBack.onShowOperationSelectDialog(new String[]{"相机"}, 0); + return; + } + if (selectFileOptions.isDCIM()) { + callBack.onShowOperationSelectDialog(new String[]{"相册"}, 1); + return; + } + if (selectFileOptions.isFileSelection()) { + callBack.onShowOperationSelectDialog(new String[]{"文件选择"}, 2); + return; + } + } + int a = View.GONE, b = View.GONE, c = View.GONE; + if (selectFileOptions.isCamera()) { + a = View.VISIBLE; + } + if (selectFileOptions.isDCIM()) { + b = View.VISIBLE; + } + if (selectFileOptions.isFileSelection()) { + c = View.VISIBLE; + } + if (selectItems == null) { + View view = LayoutInflater.from(context).inflate(R.layout.dialog_select_items, null, false); + selectItems = new AlertDialog.Builder(context) + .setView(view) + .setOnCancelListener(dialog -> { + mFilePathCallback.onReceiveValue(null); + mFilePathCallback = null; + }) + .create(); + } + selectItems.show(); + TextView tv_title = selectItems.findViewById(R.id.tv_title); + tv_title.setText("选择操作方式"); + View tv_xj = selectItems.findViewById(R.id.tv_xj); + tv_xj.setVisibility(a); + View tv_xc = selectItems.findViewById(R.id.tv_xc); + tv_xc.setVisibility(b); + View tv_wjxz = selectItems.findViewById(R.id.tv_wjxz); + tv_wjxz.setVisibility(c); + tv_xj.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + selectItems.dismiss(); + callBack.onShowOperationSelectDialog(new String[]{"相机"}, 0); + } + }); + tv_xc.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + selectItems.dismiss(); + callBack.onShowOperationSelectDialog(new String[]{"相册"}, 1); + } + }); + tv_wjxz.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + selectItems.dismiss(); + callBack.onShowOperationSelectDialog(new String[]{"文件选择"}, 2); + } + }); + } + + /** + * 显示选择文件弹框 + * + * @param whit 可操作的项 + * 1表示 只能相机拍照,将直接打开系统相机 + * 2表示 提供相机拍照、相册选取两个选项 + * 3表示 文件选取 + */ + public void onShowOperationSelectDialog(Activity activity, int whit, String[] split) { + switch (whit) { + case 0: + skipPickPhoto(activity); + break; + case 1: + Intent intent = new Intent(Intent.ACTION_PICK, null); + intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, fileTypes); + intent.setType(fileTypes); + activity.startActivityForResult(intent, SELECT_IMG_CODE); + break; + case 2: + intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.setType(fileTypes); + intent.addCategory(Intent.CATEGORY_OPENABLE); + activity.startActivityForResult(intent, SELECT_FILE_CODE); + break; + } + } + + /** + * 下载文件 + * + * @param url 文件URL + * @param fileName 文件名称 + * @param downloadListener 下载监听 + */ + public void downloadFile(String url, String fileName, DownloadUtil.OnDownloadListener downloadListener) { +// ApiModel.request(RetrofitService.getBaseInstance().downFile(url), new BaseRequestCallback() { +// @Override +// public void onRequestFailure(String msg) { +// // 下载失败 +// downloadListener.onDownloadFailed(msg); +// } +// +// @Override +// public void onRequestSuccess(ResponseBody result) { +// try { +// DownloadUtil.get().handDownFile(url,FileUtils.DOWNLOADS_DIR,result,fileName,downloadListener); +// } catch (IOException e) { +// e.printStackTrace(); +// // 下载失败 +// downloadListener.onDownloadFailed(e.getMessage()); +// } +// } +// }); + DownloadUtil.get().download(url, FileUtils.DOWNLOADS_DIR, fileName, downloadListener); + } + + public WebViewClient mWebViewClient = new WebViewClient() { + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + //do you work + LogUtils.w(String.format("onPageStarted : url=%s", url)); + if (url.startsWith(intoUrl) || url.startsWith("http://localhost")) { + if (isLogin) { + callBack.onFinish(); + } + isLogin = true; + } + } + + @Override + public void onLoadResource(WebView view, String url) { + super.onLoadResource(view, url); + } + + @Override + public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { + super.onReceivedError(view, request, error); + //net::ERR_NAME_NOT_RESOLVED -2 网页超时加载 执行这个回调 +// showLoadWebError("应用加载超时,请联系管理员排查系统。",ywryName,ywryPhone); + } + + @Override + public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) { + //内部系统 沒有用用户 +// errorResponse.getStatusCode() == 404; +// if(errorResponse.getStatusCode() == 404){ +// showLoadWebError("应用加载失败,用户没有权限,请联系管理添加权限。",ywryName,ywryPhone); +// }else { + super.onReceivedHttpError(view, request, errorResponse); +// } + } + + @Override + public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { + super.onReceivedSslError(view, handler, error); + } + + @Override + public void onPageFinished(WebView view, String url) { + view.getSettings().setBlockNetworkImage(false); + super.onPageFinished(view, url); + } + }; + + public WebChromeClient mWebChromeClient = new WebChromeClient() { + @Override + public void onProgressChanged(WebView view, int newProgress) { + //do you work + super.onProgressChanged(view, newProgress); + if (newProgress>=100){ + view.getSettings().setBlockNetworkImage(false); + } + LogUtils.w(TAG, String.format("onProgressChanged : newProgress=%s", newProgress)); + } + + @Override + public boolean onJsAlert(WebView view, String url, String message, JsResult result) { + //设置弹窗 + AlertDialog.Builder b = new AlertDialog.Builder(context); + b.setTitle("Alert"); + b.setMessage(message); + b.setPositiveButton(android.R.string.ok, (dialog, which) -> result.confirm()); + b.setCancelable(true); + b.create().show(); + return true; + } + + @Override + public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) { + mFilePathCallback = filePathCallback; + if (fileChooserParams != null) { + if (fileChooserParams.getAcceptTypes() != null + && fileChooserParams.getAcceptTypes().length > 0) { + StringBuilder builder = new StringBuilder(); + String sp = ""; + for (int i = 0; i < fileChooserParams.getAcceptTypes().length; i++) { + builder.append(sp); + builder.append(fileChooserParams.getAcceptTypes()[0]); + sp = ";"; + } + fileTypes = builder.toString(); + } + } + if (StringUtil.isNullOrEmpty(fileTypes)) { + fileTypes = "*/*"; + } + if (selectFileOptions == null) { + selectFileOptions = new SelectFileOptions(false, true, true, true); + } + if (selectFileOptions.isSelfRealization()) { + return super.onShowFileChooser(webView, filePathCallback, fileChooserParams); + } + showSelectUploadDialog(); + return true; + } + }; + + + public void showLoadWebError(String titleStr, String msg, String lxryName, String lxryPhone) { + if (StringUtil.isNullOrEmpty(titleStr)){ + titleStr = "温馨提示"; + } + View view = LayoutInflater.from(context).inflate(R.layout.dialog_h5_error, null, false); + Dialog insertTips = new AlertDialog.Builder(context) + .setView(view) + .create(); + insertTips.show(); + TextView title = insertTips.findViewById(R.id.textView2); + title.setText(titleStr); + TextView tvMsg = insertTips.findViewById(R.id.tv_msg); + TextView tvYwry = insertTips.findViewById(R.id.tv_wery); + TextView tvPhone = insertTips.findViewById(R.id.tv_ywrydh); + tvMsg.setText(msg); + String name = "暂无"; + String lxdh ="暂无"; + if (StringUtil.isNullOrEmpty(lxryName)) { + if (StringUtil.hasContent(ywryName)) { + name =ywryName; + if (StringUtil.hasContent(ywryPhone)){ + lxdh = ywryPhone; + } + } + }else { + name = lxryName; + lxdh= StringUtil.isNullOrEmpty(lxryPhone)?"暂无":lxryPhone; + } + tvYwry.setText(name+":"); + tvPhone.setText(lxdh); + insertTips.findViewById(R.id.btn_determine).setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + insertTips.dismiss(); + callBack.onFinish(); + } + }); + } + + /** + * 处理选择相册和选择文件 + * + * @param requestCode + * @param resultCode + * @param intent + */ + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) { + Uri[] results = null; + if (resultCode == Activity.RESULT_OK) { + if (intent != null) { + String dataString = intent.getDataString(); + ClipData clipData = intent.getClipData(); + if (clipData != null) { + results = new Uri[clipData.getItemCount()]; + for (int i = 0; i < clipData.getItemCount(); i++) { + ClipData.Item item = clipData.getItemAt(i); + results[i] = item.getUri(); + } + } + if (dataString != null) + results = new Uri[]{Uri.parse(dataString)}; + } + mFilePathCallback.onReceiveValue(results); + mFilePathCallback = null; + } else { + mFilePathCallback.onReceiveValue(null); + mFilePathCallback = null; + } + } + + /** + * 压缩图片 + */ + public void ysBitmap() { + BitMapUtils.lubanCompress(context, photoFile, FileUtils.IMAGE_DIR, new OnCompressListener() { + @Override + public void onStart() { + + } + + @Override + public void onSuccess(File file) { + if (!file.getAbsolutePath().equals(photoFile.getAbsolutePath())) { + photoFile.delete(); + photoFile = file; + } + Uri ph = UriUtils.getUri(context, file); + Uri[] uris = new Uri[]{ph}; + mFilePathCallback.onReceiveValue(uris); + mFilePathCallback = null; + } + + @Override + public void onError(Throwable e) { + mFilePathCallback.onReceiveValue(null); + mFilePathCallback = null; + + } + }); + } + + /** + * 浏览器下载 + * + * @param url + */ + private void downloadByBrowser(String url) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.addCategory(Intent.CATEGORY_BROWSABLE); + intent.setData(Uri.parse(url)); + context.startActivity(intent); + } + + /** + * 系统下载服务下载 + * + * @param url + * @param contentDisposition + * @param mimeType + */ + public void downloadBySystem(String url, String contentDisposition, String mimeType) { + // 指定下载地址 + DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); + // 允许媒体扫描,根据下载的文件类型被加入相册、音乐等媒体库 + request.allowScanningByMediaScanner(); + // 设置通知的显示类型,下载进行时和完成后显示通知 + request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); + // 设置通知栏的标题,如果不设置,默认使用文件名 +// request.setTitle("This is title"); + // 设置通知栏的描述 +// request.setDescription("This is description"); + // 允许在计费流量下下载 + request.setAllowedOverMetered(false); + // 允许该记录在下载管理界面可见 + request.setVisibleInDownloadsUi(false); + // 允许漫游时下载 + request.setAllowedOverRoaming(true); + // 允许下载的网路类型 + request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI); + // 设置下载文件保存的路径和文件名 + String fileName = URLUtil.guessFileName(url, contentDisposition, mimeType); + LogUtils.d("fileName:{}", fileName); + request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); +// 另外可选一下方法,自定义下载路径 +// request.setDestinationUri() +// request.setDestinationInExternalFilesDir() + final DownloadManager downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE); + // 添加一个下载任务 + long downloadId = downloadManager.enqueue(request); + LogUtils.d("downloadId:{}", downloadId + ""); + } + + + /** + * 打开GPS + */ +// private void openGPSSettings() { +// LocationManager alm = (LocationManager) context +// .getSystemService(Context.LOCATION_SERVICE); +// if (alm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) { +// Toast.makeText(context, "GPS模块正常", Toast.LENGTH_SHORT).show(); +//// baiDuMapManager.startLocation(); +// return; +// } else { +// Toast.makeText(context, "请开启GPS!", Toast.LENGTH_SHORT).show(); +// Intent intent = new Intent(Settings.ACTION_SECURITY_SETTINGS); +// startActivityForResult(intent, 0); // 此为设置完成后返回到获取界面 +// } +// } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/request/ApiModel.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/ApiModel.java new file mode 100644 index 0000000..dcc3850 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/ApiModel.java @@ -0,0 +1,633 @@ +package com.ycgis.macall.personalcenter.p.request; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.RequestCallback; +import com.ycgis.macall.personalcenter.p.rxjava.ResultObserver; +import com.ycgis.macall.personalcenter.util.ParamMap; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import io.reactivex.Observable; +import io.reactivex.ObservableSource; +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; +import io.reactivex.schedulers.Schedulers; +import okhttp3.MediaType; +import okhttp3.RequestBody; + +/** + * @Author macall + * @Create 2020/6/23 0023 + * @Describe 接口封装类 + */ +public class ApiModel { + private static final String TAG = "ApiModel"; + +// /** +// * 下载文件 +// * +// * @param url 下载链接 +// * @param fileName 下载后文件名 +// * @param downloadInfo 需要更新的实体 +// * @param pointer 需要更新的指针 +// * @param callBack 回调监听 +// */ + /* public static void download(Resources resources, String url, final String fileName, final DownloadOV downloadInfo, final int pointer, final DownloadCallBack callBack) { + RetrofitService.getBaseInstance() + .downloadFile(url) + .subscribeOn(Schedulers.io()) + .unsubscribeOn(Schedulers.io()) + .flatMap(new Function>() { + + @Override + public ObservableSource apply(final ResponseBody responseBody) throws Exception { + return Observable.create(new ObservableOnSubscribe() { + @Override + public void subscribe(ObservableEmitter emitter) throws Exception { + InputStream inputStream = null; + long total = 0; + long responseLength = 0; + FileOutputStream fos = null; + try { + byte[] buf = new byte[2048]; + int len = 0; + responseLength = responseBody.contentLength(); + inputStream = responseBody.byteStream(); + String fileDir = ""; +// if (downloadInfo.getType() == 1) { +// fileDir = FileUtil.getTxlPath(); +// } else if (downloadInfo.getType() == 2) { +// String extension = FileUtil.getFileExtension(fileName); +// fileDir = ResDrawableIdHelp.getFileDir(extension); +// } + final File file = new File(fileDir, fileName); + downloadInfo.setFile(file); + downloadInfo.setFileSize(responseLength); + fos = new FileOutputStream(file); + int progress = 0; + int lastProgress = 0; + long startTime = System.currentTimeMillis(); // 开始下载时获取开始时间 + while ((len = inputStream.read(buf)) != -1) { + fos.write(buf, 0, len); + total += len; + lastProgress = progress; + progress = (int) (total * 100 / responseLength); + long curTime = System.currentTimeMillis(); + long usedTime = (curTime - startTime) / 1000; + if (usedTime == 0) { + usedTime = 1; + } + long speed = (total / usedTime); // 平均每秒下载速度 + // 如果进度与之前进度相等,则不更新,如果更新太频繁,则会造成界面卡顿 + if (progress > 0 && progress != lastProgress) { + downloadInfo.setSpeed(speed); + downloadInfo.setProgress(progress); + downloadInfo.setCurrentSize(total); + emitter.onNext(downloadInfo); + } + } + fos.flush(); + downloadInfo.setFile(file); + emitter.onComplete(); + } catch (Exception e) { + downloadInfo.setErrorMsg(e); + emitter.onError(e); + } finally { + try { + if (fos != null) { + fos.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + try { + if (inputStream != null) { + inputStream.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + }); + } + }) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + } + + @Override + public void onNext(DownloadOV downloadInfo) { + callBack.onProgress(downloadInfo.getProgress(), downloadInfo.getFileSize(), downloadInfo.getSpeed()); + callBack.onProgress(downloadInfo, pointer); + + } + + @Override + public void onError(Throwable e) { + callBack.onError(e, pointer); + } + + @Override + public void onComplete() { + LogUtils.e(TAG, "完成"); + downloadInfo.setDownload(1); + callBack.onCompleted(downloadInfo, pointer); + } + }); + } + + *//*上传文件*//* + public static void uploadFile(int pointer, File file, FileItem item, String fileType, final UploadCallBack callback) { + //设置文件设置图片的格式 + RequestBody requestBody = RequestBody.create(getMediaType(file.getName()), file); + String str = file.getName(); + try { + str = URLEncoder.encode(file.getName(), "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + str = System.currentTimeMillis() + str.substring(str.lastIndexOf(".")); + } + Map map = new HashMap<>(); + map.put("files", file.getName()); + map.put("fileType", fileType); + + //设置一个file文件 + MultipartBody.Part body = MultipartBody.Part.createFormData("files", str, requestBody); +// RetrofitService.getBaseInstance() +// .uploadFile(RuanSiApplication.getAppCacheData().getUserCode() +// , RuanSiApplication.getAppCacheData().getSfzh(), RuanSiApplication.getAppCacheData().getUserName(), RuanSiApplication.getAppCacheData().getZzjgDm(), body, fileType) +// .subscribeOn(Schedulers.io()) +// .doOnSubscribe(new Consumer() { +// @Override +// public void accept(@io.reactivex.annotations.NonNull Disposable disposable) throws Exception { +// callback.onStartRequest(); +// } +// }) +// //获得的数据返回主线程去更新界面 +// .observeOn(AndroidSchedulers.mainThread()) +// .subscribe(new Observer() { +// @Override +// public void onSubscribe(Disposable d) { +//// LogUtils.w(TAG, "onSubscribe " + d.toString()); +// } +// +// @Override +// public void onNext(JsonObject s) { +//// mode.setStatus(0).setJsonResult(s.toString()).sendLog(); +//// callback.onRequestSuccess(pointer, item, s); +// } +// +// @Override +// public void onError(Throwable e) { +//// callback.onRequestFailure(pointer, item, e); +//// LogUtils.w(TAG, "onError " + e.getMessage()); +// } +// +// @Override +// public void onComplete() { +// } +// }); + }*/ + /** + * 发起请求 + * + * @param requestKey {@link CommonCompositeManage#addDisposable(String, Disposable)} 接口请求标识 用来管理 请求 + * @param observable 请求体 + * @param callback 接口回调 + * @param 返回类型 + */ + public static void requestRetry( String requestKey, Observable observable, final RequestCallback callback) { + requestRetry( observable, new Observer() { + @Override + public void onSubscribe(@NotNull Disposable d) { + CommonCompositeManage.getInstance().addDisposable(requestKey, d); + } + + @Override + public void onNext(@NotNull T t) { + CommonCompositeManage.getInstance().unDisposable(requestKey); + callback.onRequestSuccess(t); + + } + + @Override + public void onError(@NotNull Throwable e) { + CommonCompositeManage.getInstance().unDisposable(requestKey); + callback.onRequestFailure(e); + } + + @Override + public void onComplete() { + CommonCompositeManage.getInstance().unDisposable(requestKey); + } + }); + + } + /** + * 请求发生IO(time out) 异常时重新请求(重复3次) + * @param observable 被观察者(请求对象) + * @param observer 观察者(响应对象) + * @param 返回数据类型 + */ + public static void requestRetry(Observable observable, Observer observer) { + observable.retryWhen(new MyFunction, ObservableSource>() { + @Override + public ObservableSource apply(@NotNull Observable throwableObservable) throws Exception { + return throwableObservable.flatMap(new MyFunction>() { + @Override + public Observable apply(@NotNull Throwable throwable) throws Exception { + // 输出异常信息 + LogUtils.d(TAG, "发生异常 = " + throwable.toString()); + /** + * 需求1:根据异常类型选择是否重试 + * 即,当发生的异常 = 网络异常 = IO异常 才选择重试 + */ + if (throwable instanceof IOException) { + LogUtils.d(TAG, "属于IO异常,需重试"); + /** + * 需求2:限制重试次数 + * 即,当已重试次数 < 设置的重试次数,才选择重试 + */ + if (currentRetryCount < maxConnectCount) { + // 记录重试次数 + currentRetryCount++; + LogUtils.d(TAG, "重试次数 = " + currentRetryCount); + /** + * 需求2:实现重试 + * 通过返回的Observable发送的事件 = Next事件,从而使得retryWhen()重订阅,最终实现重试功能 + * + * 需求3:延迟1段时间再重试 + * 采用delay操作符 = 延迟一段时间发送,以实现重试间隔设置 + * + * 需求4:遇到的异常越多,时间越长 + * 在delay操作符的等待时间内设置 = 每重试1次,增多延迟重试时间1s + */ + // 设置等待时间 + waitRetryTime = currentRetryCount * 500; + LogUtils.d(TAG, "等待时间 =" + waitRetryTime); + return Observable.just(1).delay(waitRetryTime, TimeUnit.MILLISECONDS); + } else { + // 若重试次数已 > 设置重试次数,则不重试 + // 通过发送error来停止重试(可在观察者的onError()中获取信息) + return Observable.error(new Throwable("接口请求超时,请重试!")); + } + } + // 若发生的异常不属于I/O异常,则不重试 + // 通过返回的Observable发送的事件 = Error事件 实现(可在观察者的onError()中获取信息) + else { + return Observable.error(throwable); + } + } + }); + } + }).subscribeOn(Schedulers.io()) + .doOnSubscribe(new Consumer() { + @Override + public void accept(Disposable disposable) throws Exception { + } + }) + //获得的数据返回主线程去更新界面 + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(observer); + } + + /** + * 发起请求 + * + * @param requestKey {@link CommonCompositeManage#addDisposable(String, Disposable)} 接口请求标识 用来管理 请求 + * @param observable 请求体 + * @param callback 接口回调 + * @param 返回类型 + */ + public static void request(final String requestKey, Observable observable, final RequestCallback callback) { + request(observable, new ResultObserver(requestKey) { + @Override + protected void onNext(String identifierKey, @NotNull T data) { + if (callback!=null){ + callback.onRequestSuccess(data); + } + CommonCompositeManage.getInstance().unDisposable(identifierKey); + } + + @Override + public void onSubscribe(String identifierKey, @NotNull Disposable d) { + CommonCompositeManage.getInstance().addDisposable(identifierKey, d); + } + + + @Override + public void onError(String identifierKey, @NotNull Throwable e) { + LogUtils.w(TAG, "onError " + e.getMessage()); + if (callback!=null){ + callback.onRequestFailure(e); + } + CommonCompositeManage.getInstance().unDisposable(identifierKey); + } + + @Override + public void onComplete(String identifierKey) { + CommonCompositeManage.getInstance().unDisposable(identifierKey); + } + }, callback); + } + + /** + * 发起请求 + * + * @param observable 请求体 + * @param callback 接口回调 + * @param 返回类型 + */ + public static void request(Observable observable, final RequestCallback callback) { + request(observable, new Observer() { + @Override + public void onSubscribe(Disposable d) { +// LogUtils.w(TAG, "onSubscribe " + d.toString()); + } + + @Override + public void onNext(T s) { + LogUtils.w(TAG, "onSubscribe " + s.toString()); + callback.onRequestSuccess(s); + } + + @Override + public void onError(Throwable e) { + callback.onRequestFailure(e); + LogUtils.w(TAG, "onError " + e.getMessage()); + } + + @Override + public void onComplete() { + LogUtils.w(TAG, "onComplete "); + } + }, callback); + } + +// public static void request(Observable observable, Observer observer, final RequestCallback callback) { +// observable +// .subscribeOn(Schedulers.io()) +// .doOnSubscribe(new Consumer() { +// @Override +// public void accept(@io.reactivex.annotations.NonNull Disposable disposable) throws Exception { +// if (callback != null) { +// callback.onStartRequest(); +// } +// } +// }) +// //获得的数据返回主线程去更新界面 +// .observeOn(AndroidSchedulers.mainThread()) +// .subscribe(observer); +// } +// + public static void request(Observable observable, Observer observer, final RequestCallback callback) { + observable.retryWhen(new MyFunction, ObservableSource>() { + @Override + public ObservableSource apply(@NotNull Observable throwableObservable) throws Exception { + return throwableObservable.flatMap(new MyFunction>() { + @Override + public Observable apply(@NotNull Throwable throwable) throws Exception { + // 输出异常信息 + LogUtils.d(TAG, "发生异常 = " + throwable.toString()); + /** + * 需求1:根据异常类型选择是否重试 + * 即,当发生的异常 = 网络异常 = IO异常 才选择重试 + */ + + if (throwable instanceof IOException || throwable instanceof TimeoutException) { + LogUtils.d(TAG, "属于IO异常,需重试"); + /** + * 需求2:限制重试次数 + * 即,当已重试次数 < 设置的重试次数,才选择重试 + */ + if (currentRetryCount < maxConnectCount) { + // 记录重试次数 + currentRetryCount++; + LogUtils.d(TAG, "重试次数 = " + currentRetryCount); + /** + * 需求2:实现重试 + * 通过返回的Observable发送的事件 = Next事件,从而使得retryWhen()重订阅,最终实现重试功能 + * + * 需求3:延迟1段时间再重试 + * 采用delay操作符 = 延迟一段时间发送,以实现重试间隔设置 + * + * 需求4:遇到的异常越多,时间越长 + * 在delay操作符的等待时间内设置 = 每重试1次,增多延迟重试时间1s + */ + // 设置等待时间 + waitRetryTime = currentRetryCount * 500; + LogUtils.d(TAG, "等待时间 =" + waitRetryTime); + return Observable.just(1).delay(waitRetryTime, TimeUnit.MILLISECONDS); + } else { + // 若重试次数已 > 设置重试次数,则不重试 + // 通过发送error来停止重试(可在观察者的onError()中获取信息) + return Observable.error(new Throwable("接口请求超时,请重试!")); + } + } + // 若发生的异常不属于I/O异常,则不重试 + // 通过返回的Observable发送的事件 = Error事件 实现(可在观察者的onError()中获取信息) + else { + return Observable.error(throwable); + } + } + }); + } + }) + .subscribeOn(Schedulers.io()) + .doOnSubscribe(new Consumer() { + @Override + public void accept(@io.reactivex.annotations.NonNull Disposable disposable) throws Exception { + if (callback != null) { + callback.onStartRequest(); + } + } + }) + //获得的数据返回主线程去更新界面 + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(observer); + } + + /** + * 全部在IO线程执行,不需要切换至UI线程 + * + * @param observable 接口 + * @param callback 接收返回结果的监听接口 + * @param 返回参数泛型 + */ + public static void requestIO(final String requestKey, Observable observable, final RequestCallback callback) { + requestIO(observable, new ResultObserver(requestKey) { + @Override + protected void onSubscribe(String identifierKey, @NotNull Disposable d) { + CommonCompositeManage.getInstance().addDisposable(identifierKey,d); + } + + @Override + protected void onNext(String identifierKey, @NotNull T data) { + CommonCompositeManage.getInstance().unDisposable(identifierKey); + if (callback!=null){ + callback.onRequestSuccess(data); + } + } + + @Override + protected void onError(String identifierKey, @NotNull Throwable data) { + if (callback!=null){ + callback.onRequestFailure(data); + } + CommonCompositeManage.getInstance().unDisposable(identifierKey); + } + + @Override + protected void onComplete(String identifierKey) { + CommonCompositeManage.getInstance().unDisposable(identifierKey); + } + }, callback); + } + + /** + * 全部在IO线程执行,不需要切换至UI线程 + * + * @param observable 接口 + * @param callback 接收返回结果的监听接口 + * @param 返回参数泛型 + */ + public static void requestIO(Observable observable, final RequestCallback callback) { + requestIO(observable, new Observer() { + @Override + public void onSubscribe(Disposable d) { + LogUtils.w(TAG, "onSubscribe " + d.toString()); + } + + @Override + public void onNext(T s) { + if (callback != null) + callback.onRequestSuccess(s); + } + + @Override + public void onError(Throwable e) { + if (callback != null) + callback.onRequestFailure(e); + LogUtils.w(TAG, "onError " + e.getMessage()); + } + + @Override + public void onComplete() { + LogUtils.w(TAG, "onComplete "); + } + }, callback); + } + + /** + * 全部在IO线程执行,不需要切换至UI线程 + * + * @param observable 请求体 + * @param observer + * @param callback 接收返回结果的监听接口 + * @param 返回参数泛型 + */ + public static void requestIO(Observable observable, Observer observer, final RequestCallback callback) { + observable + .subscribeOn(Schedulers.io()) + .doOnSubscribe(new Consumer() { + @Override + public void accept(@io.reactivex.annotations.NonNull Disposable disposable) throws Exception { + if (callback != null) + callback.onStartRequest(); + } + }) + //获得的数据返回主线程去更新界面 + .observeOn(Schedulers.io()) + .subscribe(observer); + } + + /*private static MediaType getMediaType(String fileName) { + MediaType mediaType = MediaType.parse("application/octet-stream"); + if (fileName.endsWith(".jpg")) { + mediaType = MediaType.parse("image/jpg"); + } else if (fileName.endsWith(".png")) { + mediaType = MediaType.parse("image/png"); + } else if (fileName.endsWith(".jpeg")) { + mediaType = MediaType.parse("image/jpeg"); + } else if (fileName.endsWith(".mp4")) { + mediaType = MediaType.parse("video/mp4"); + } else if (fileName.endsWith(".mp3")) { + mediaType = MediaType.parse("audio/mpeg"); + } else if (fileName.endsWith(".json")) { + mediaType = MediaType.parse("application/json"); + } else if (fileName.endsWith(".jar")) { + mediaType = MediaType.parse("application/java-archive"); + } else if (fileName.endsWith(".html")) { + mediaType = MediaType.parse("text/html"); + } else if (fileName.endsWith(".gif")) { + mediaType = MediaType.parse("image/gif"); + } + return mediaType; + }*/ + + + /** + * 上传统一日志,前端 无感知,不关心结果 + * @param logLevel 1 = ALL | 2 = debug | 3 = info | 4 = Warn | 5 = Error | 6 = FATAL | 7 OFF + * 正常日志传 3,错误日志传5,应用报错日志传 6 + * @param optType 1 = 业务日志 | 2 = 安全日志 3 = 操作日志 | 4 = 其他 + * @param content 日志内容 + */ + public static void uploadOperationLog(String logLevel, String optType, String content) { + ParamMap map = new ParamMap(); +// map.put("sysCode", "adde349491f64c0980ce59bd882bff53"); + //个人中心日志代码 + map.put("sysCode", "b581b2a86bc10ade016bd5a74e880001"); + map.put("logType", "3"); + map.put("logLevel", logLevel); + map.put("optUserNum", RuanseeApplication.getUserData().getUserCode()); + map.put("optUserName", RuanseeApplication.getUserData().getUserName()); + map.put("optOrgCode", RuanseeApplication.getUserData().getDeptCode()); + map.put("optOrgName", RuanseeApplication.getUserData().getDeptName()); + map.put("optType", optType); + map.put("content", content); + map.put("ip", RuanseeApplication.getAppCache().getLocalIp()); + //String转RequestBody String、ByteArray、ByteString都可以用toRequestBody() + MediaType mediaType = MediaType.Companion.parse("application/json;charset=utf-8"); + RequestBody stringBody = RequestBody.Companion.create(new Gson().toJson(map.apply()), mediaType); + RetrofitService.getBaseInstance() + .uploadOperationLog("http://20.90.1.142:7350/api/log/save",stringBody) + .subscribeOn(Schedulers.io()) + //获得的数据返回主线程去更新界面 + .observeOn(Schedulers.io()) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NotNull Disposable d) { + + } + + @Override + public void onNext(@NotNull JsonObject jsonObject) { + LogUtils.w(jsonObject.toString()); + } + + @Override + public void onError(@NotNull Throwable e) { + LogUtils.e(e.getMessage()); + } + + @Override + public void onComplete() { + + } + }); + + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/request/AsyncBitmapLoader.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/AsyncBitmapLoader.java new file mode 100644 index 0000000..6fe9b05 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/AsyncBitmapLoader.java @@ -0,0 +1,265 @@ +package com.ycgis.macall.personalcenter.p.request; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Handler; +import android.os.Message; +import android.widget.ImageView; + +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.request.OkHttpUtils; +import com.rs.macall.androidx.basemodel.utils.BitMapUtils; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.callback.ImageCallBack; +import com.ycgis.macall.personalcenter.util.FileUtils; +import com.ycgis.macall.personalcenter.v.activity.applyfo.ApplyForMainActivity; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.io.IOException; +import java.lang.ref.SoftReference; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.Request; +import okhttp3.Response; +import top.zibin.luban.OnCompressListener; + +public class AsyncBitmapLoader { + + /** + * 内存图片软引用缓冲 + */ + private HashMap> imageCache = null; + private File files; + + public AsyncBitmapLoader() { + imageCache = new HashMap>(); + } + + /* public Bitmap loadBitmap(final Context context, final ZdyText imageView, final String imageURL, final ImageCallBack imageCallBack) { + //在内存缓存中,则返回Bitmap对象 + if (imageCache.containsKey(imageURL)) { + SoftReference reference = imageCache.get(imageURL); + Bitmap bitmap = reference.get(); + if (bitmap != null) { + return bitmap; + } + } else { + *//** + * 加上一个对本地缓存的查找 + *//* + final File cacheDir; + if (imageURL.startsWith("/storage/emulated")) { + cacheDir = new File(imageURL); + } else { + String bitmapName = imageURL.substring(imageURL.lastIndexOf("/") + 1); + cacheDir = new File(FileUtils.IMAGE_DIR + bitmapName); + } + if (cacheDir.exists()) { + try { + return BitmapFactory.decodeFile(cacheDir.getAbsolutePath()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @SuppressLint("HandlerLeak") final Handler handler = new Handler() { + *//* (non-Javadoc) + * @see android.os.Handler#handleMessage(android.os.Message) + *//* + @Override + public void handleMessage(final Message msg) { + // TODO Auto-generated method stub + switch (msg.what) { + case -2001: + imageCallBack.imageLoadError(imageView, (String) msg.obj); + break; + case 200: + Bitmap bitmap = (Bitmap) msg.obj; + String lswn = System.currentTimeMillis() + ""; + lswn += new Random().nextInt(10) + ".jpg"; + files = BitMapUtils.saveBitmap(FileUtils.IMAGE_DIR, lswn, bitmap); + if (files == null || !files.exists()) { + imageCallBack.imageLoadError(imageView, "图片加载失败!"); + return; + } + String fileName = imageURL.substring(imageURL.lastIndexOf("/") + 1); + ys(context, fileName, this); + break; + case 1414: + Bitmap bitmap1 = (Bitmap) msg.obj; + imageCallBack.imageLoad(imageView, bitmap1); + imageCache.put(imageURL, new SoftReference(bitmap1)); + break; + case -2121: + imageCallBack.imageLoadError(imageView, (String) msg.obj); + break; + } + } + }; + + //如果不在内存缓存中,也不在本地(被jvm回收掉),则开启线程下载图片 + getGetPhtot(AppCache.IMAGE_URL + imageURL, handler); + + } + return null; + } +*/ + private void ys(Context context, final String newFileName, final Handler handler) { + BitMapUtils.lubanCompress(context, files, FileUtils.IMAGE_DIR, new OnCompressListener() { + @Override + public void onStart() { + + } + + @Override + public void onSuccess(File file) { + if (!files.getName().equals(file.getName())) + files.delete(); + boolean is = FileUtils.renameFile(FileUtils.IMAGE_DIR, file.getName(), newFileName); + if (is) { + Bitmap bitmap1 = BitmapFactory.decodeFile(FileUtils.IMAGE_DIR + newFileName); + Message message = handler.obtainMessage(1414, bitmap1); + handler.sendMessage(message); + } + } + + @Override + public void onError(Throwable e) { + Message message = handler.obtainMessage(-2121, "图片加载失败!"); + handler.sendMessage(message); + } + }); + } + + /** + * GET 方式请求数据 图片 + */ + public static void getGetPhtot(String urlTal, final Handler handler) { + URL url = null; + try { + url = new URL(urlTal); + } catch (MalformedURLException e) { + e.printStackTrace(); + Message message = handler.obtainMessage(); + message.what = -2001; + message.arg2 = 205; + message.obj = "URL错误"; + handler.sendMessage(message); + return; + } + Request request = new Request.Builder() + .url(url) + .build(); + OkHttpUtils.getClient(10, 30, 40) + .newCall(request) + .enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + System.out.println("加载图片错误:" + e.getMessage()); + Message message = handler.obtainMessage(); + message.what = -2001; + message.arg2 = 205; + message.obj = "加载图片失败:请检查网络连接状况"; + handler.sendMessage(message); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + int responseCode = response.code(); + if (responseCode != 200) { + System.out.println("加载图片错误:请求码错误"); + Message message = handler.obtainMessage(); + message.what = -2001; + message.arg2 = 205; + message.obj = "加载图片失败,请联系管理员"; + handler.sendMessage(message); + return; + } + byte[] photoByte = response.body().bytes(); + Message message = new Message(); + message.what = 200; + message.arg2 = 205; + message.obj = BitmapFactory.decodeByteArray(photoByte, 0, photoByte.length); + handler.sendMessage(message); + } + }); + } + + public Bitmap loadSeal(String id,String deptCode,ImageView imageView,final ImageCallBack callback) { + if (imageCache == null){ + imageCache = new HashMap<>(); + } + SoftReference bitmapSoftReference = imageCache.get(deptCode); + if (bitmapSoftReference != null&&bitmapSoftReference.get() != null){ + return bitmapSoftReference.get(); + } + File file = new File(FileUtils.IMAGE_DIR,deptCode+".png"); + if (file.exists()){ + return BitmapFactory.decodeFile(file.getAbsolutePath()); + } + Map headMap = new HashMap<>(1); + headMap.put("app-yysq-token", RuanseeApplication.getAppCache().getApply_token()); + ApiModel.request(RetrofitService.getBaseInstance().applyGet(ApplyForMainActivity.BASE_URL + "audit/seal/" + id, headMap, new HashMap<>()), new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(msg); + callback.imageLoadError(imageView,msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + LogUtils.w(result.toString()); + try { + JSONObject object = new JSONObject(result.toString()); + int code = TypConversion.getJsonInt(object, "code", 0); + if (code == 200){ + JSONObject data = TypConversion.getJSONObject(object, "data"); + String seal_img = TypConversion.getJsonStr(data, "seal_img"); + Bitmap bitmap = BitMapUtils.base64ToBitmap(seal_img); + if (bitmap!=null){ + Bitmap bitmap1 = BitMapUtils.removeWhiteBackground(bitmap); + if (imageCache == null){ + imageCache = new HashMap<>(); + } + imageCache.put(deptCode, new SoftReference<>(bitmap1)); + BitMapUtils.saveBitmap(FileUtils.IMAGE_DIR,deptCode+".png",bitmap1); + callback.imageLoad(imageView,bitmap1); + }else { + callback.imageLoadError(imageView,"加载失败"); + } + }else { + callback.imageLoadError(imageView,"加载失败"); + } + } catch (JSONException e) { + e.printStackTrace(); + callback.imageLoadError(imageView,"加载失败"); + } +// new SoftReference<>() +// SoftReference bitmapSoftReference = imageCache.get(deptCode); +// +// +// if (bitmapSoftReference != null&&bitmapSoftReference.get() != null){ +// return bitmapSoftReference.get(); +// } +// File file = new File(FileUtils.IMAGE_DIR,deptCode+".jpg"); +// if (file.exists()){ +// return BitmapFactory.decodeFile(file.getAbsolutePath()); +// } + } + }); + return null; + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/request/CommonComposite.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/CommonComposite.java new file mode 100644 index 0000000..bb3919a --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/CommonComposite.java @@ -0,0 +1,22 @@ +package com.ycgis.macall.personalcenter.p.request; + +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.disposables.Disposable; + +public class CommonComposite { + private CompositeDisposable mCompositeDisposable; + + public void addDisposable(Disposable disposable) { + if (mCompositeDisposable == null || mCompositeDisposable.isDisposed()) { + mCompositeDisposable = new CompositeDisposable(); + } + mCompositeDisposable.add(disposable); + } + + public void unDisposable() { + if (mCompositeDisposable != null) { + mCompositeDisposable.dispose(); + } + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/request/CommonCompositeManage.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/CommonCompositeManage.java new file mode 100644 index 0000000..ad5fe9b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/CommonCompositeManage.java @@ -0,0 +1,88 @@ +package com.ycgis.macall.personalcenter.p.request; + + +import com.ycgis.macall.personalcenter.p.callback.RequestCallback; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import io.reactivex.Observable; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.disposables.Disposable; + +/** + * 负责 请求时activity退出 取消请求 + */ +public class CommonCompositeManage { + private static CommonCompositeManage commonCompositeManage; + //用于存放 请求的 + private Map manage; + + private CommonCompositeManage(){ + manage = new HashMap<>(); + } + + public synchronized static CommonCompositeManage getInstance(){ + if (commonCompositeManage == null){ + synchronized (CommonCompositeManage.class){ + if (commonCompositeManage == null) + commonCompositeManage = new CommonCompositeManage(); + } + } + return commonCompositeManage; + } + + //添加一个请求 + + /** + * 添加一个请求 + * 该方法会在请求发起的时候自动调用 {@link ApiModel#requestRetry(String, Observable, RequestCallback)} + * @param key 请求标识 + * @param disposable 请求 + */ + public void addDisposable(String key, Disposable disposable){ + CompositeDisposable compositeDisposable = manage.get(key); + if (compositeDisposable == null||compositeDisposable.isDisposed()){ + compositeDisposable = new CompositeDisposable(); + } + compositeDisposable.add(disposable); + manage.put(key,compositeDisposable); + } + + /** + * 取消一个请求 {@link #addDisposable(String, Disposable)} 取消在这里添加的请求 + * 该方法在请求完成后回自动调用 @see{@link ApiModel#request(String, Observable, RequestCallback)} + * 为了应用安全,应当在 Activity、Fragment 的onDestroy() 方法里主动调用,这样当请求还未完成时 Activity、Fragment 销毁时取消请求 + * @param key 请求标识 + */ + public void unDisposable(String key){ + CompositeDisposable compositeDisposable = manage.get(key); + if (compositeDisposable != null&&!compositeDisposable.isDisposed()){ + compositeDisposable.dispose(); + } + manage.remove(key); + } + + /** + * 取消所有请求 + * 该发放需要主动调用,建议在 MAIN Activity 的 onDestroy() 方法里调用 + */ + public void destory(){ + if (manage==null) return; + if (manage.isEmpty()) return; + Set strings = manage.keySet(); + Iterator iterator = strings.iterator(); + while (iterator.hasNext()){ + String next = iterator.next(); + CompositeDisposable compositeDisposable = manage.get(next); + if (compositeDisposable != null&&!compositeDisposable.isDisposed()){ + compositeDisposable.dispose(); + } + } + manage.clear(); + manage = null ; + commonCompositeManage = null; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/request/DownloadUtil.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/DownloadUtil.java new file mode 100644 index 0000000..1cceea3 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/DownloadUtil.java @@ -0,0 +1,282 @@ +package com.ycgis.macall.personalcenter.p.request; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Environment; + +import androidx.annotation.NonNull; + +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; + +/** + * created by: Macall + * create time: 2022/11/21 17:39 + * copyright: @ruansee.com + * Describe: + */ +public class DownloadUtil { + private static final String TAG = DownloadUtil.class.getName(); + private static DownloadUtil downloadUtil; + private final OkHttpClient okHttpClient; + + public static DownloadUtil get() { + if (downloadUtil == null) { + downloadUtil = new DownloadUtil(); + } + return downloadUtil; + } + + private DownloadUtil() { + okHttpClient = new OkHttpClient.Builder() + .connectTimeout(20, TimeUnit.SECONDS) + .writeTimeout(20, TimeUnit.SECONDS) + .readTimeout(60, TimeUnit.SECONDS).build(); +// new OkHttpClient(); + } + + /** + * 复制单个文件 + * + * @param oldPath$Name String 原文件路径+文件名 如:data/user/0/com.test/files/abc.txt + * @param newPath$Name String 复制后路径+文件名 如:data/user/0/com.test/cache/abc.txt + * @return true if and only if the file was copied; + * false otherwise + */ + public static boolean copyFile(String oldPath$Name, String newPath$Name) { + try { + File oldFile = new File(oldPath$Name); + if (!oldFile.exists()) { + LogUtils.e("--Method--", "copyFile: oldFile not exist."); + return false; + } else if (!oldFile.isFile()) { + LogUtils.e("--Method--", "copyFile: oldFile not file."); + return false; + } else if (!oldFile.canRead()) { + LogUtils.e("--Method--", "copyFile: oldFile cannot read."); + return false; + } + + /* 如果不需要打log,可以使用下面的语句 + if (!oldFile.exists() || !oldFile.isFile() || !oldFile.canRead()) { + return false; + } + */ + + FileInputStream fileInputStream = new FileInputStream(oldPath$Name); + FileOutputStream fileOutputStream = new FileOutputStream(newPath$Name); + byte[] buffer = new byte[1024]; + int byteRead; + while (-1 != (byteRead = fileInputStream.read(buffer))) { + fileOutputStream.write(buffer, 0, byteRead); + } + fileInputStream.close(); + fileOutputStream.flush(); + fileOutputStream.close(); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 通知相册更新 + * + * @param context + * @param newFile + */ + public void updateDCIM(Context context, File newFile) { + File cameraPath = new File(dcimPath, "Camera"); + File imgFile = new File(cameraPath, newFile.getAbsolutePath()); + if (imgFile.exists()) { + Uri uri = Uri.fromFile(imgFile); + Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + intent.setData(uri); + context.sendBroadcast(intent); + } + } + + /** + * url 下载连接 + * saveDir 储存下载文件的SDCard目录 + * listener 下载监听 + */ + public void download(final String url, final String saveDir,String fileName, + final OnDownloadListener listener) { + Request request = new Request.Builder().url(url).build(); + okHttpClient.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + // 下载失败 + listener.onDownloadFailed(e.getMessage()); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + InputStream is = null; + byte[] buf = new byte[2048]; + int len = 0; + FileOutputStream fos = null; + // 储存下载文件的目录 + String savePath = isExistDir(saveDir); + try { + is = response.body().byteStream(); + long total = response.body().contentLength(); + String nameFromUrl =fileName; + if (StringUtil.isNullOrEmpty(nameFromUrl)){ + nameFromUrl = getNameFromUrl(url); + } + File file = new File(savePath, nameFromUrl); + fos = new FileOutputStream(file); + long sum = 0; + while ((len = is.read(buf)) != -1) { + fos.write(buf, 0, len); + sum += len; + int progress = (int) (sum * 1.0f / total * 100); + // 下载中 + listener.onDownloading(progress); + } + fos.flush(); + // 下载完成 + listener.onDownloadSuccess(file); + } catch (Exception e) { + listener.onDownloadFailed(e.getMessage()); + } finally { + try { + if (is != null) + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + if (fos != null) + fos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + }); + } + + public void handDownFile(String url, String saveDir, ResponseBody response, String fileName, OnDownloadListener listener) throws IOException { + InputStream is = null; + byte[] buf = new byte[2048]; + int len = 0; + FileOutputStream fos = null; + // 储存下载文件的目录 + String savePath = isExistDir(saveDir); + try { + is = response.byteStream(); + long total = response.contentLength(); + String nameFromUrl =fileName; + if (StringUtil.isNullOrEmpty(nameFromUrl)){ + nameFromUrl = getNameFromUrl(url); + } + File file = new File(savePath, nameFromUrl); + fos = new FileOutputStream(file); + long sum = 0; + while ((len = is.read(buf)) != -1) { + fos.write(buf, 0, len); + sum += len; + int progress = (int) (sum * 1.0f / total * 100); + // 下载中 + listener.onDownloading(progress); + } + fos.flush(); + // 下载完成 + listener.onDownloadSuccess(file); + } catch (Exception e) { + listener.onDownloadFailed(e.getMessage()); + } finally { + try { + if (is != null) + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + if (fos != null) + fos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * saveDir + * 判断下载目录是否存在 + */ + private static String isExistDir(String saveDir) throws IOException { + // 下载位置 + File downloadFile = new File(saveDir); + if (!downloadFile.mkdirs()) { + downloadFile.createNewFile(); + } + String savePath = downloadFile.getAbsolutePath(); + return savePath; + } + + //系统相册路径 + static String dcimPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath(); + + /** + * 创建文件夹 + */ + public static void createFiles(File oldFile) { + try { + File file = new File(isExistDir(dcimPath + "/xxx")); + String newPath = file.getPath() + "/" + oldFile.getName(); + LogUtils.d("TAG", "createFiles111: " + oldFile.getPath() + "--" + newPath); + if (copyFile(oldFile.getPath(), newPath)) { + LogUtils.d("TAG", "createFiles222: " + oldFile.getPath() + "--" + newPath); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + + /** + * url + * 从下载连接中解析出文件名 + */ + @NonNull + public static String getNameFromUrl(String url) { + return url.substring(url.lastIndexOf("/") + 1); + } + + public interface OnDownloadListener { + /** + * 下载成功 + */ + void onDownloadSuccess(File file); + + /** + * @param progress 下载进度 + */ + void onDownloading(int progress); + + /** + * 下载失败 + */ + void onDownloadFailed(String msg); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/request/HttpErrorHandler.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/HttpErrorHandler.java new file mode 100644 index 0000000..4f0f38f --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/HttpErrorHandler.java @@ -0,0 +1,71 @@ +package com.ycgis.macall.personalcenter.p.request;/* + * 项目名:xayss + * 作者:马超 + * 类目:HttpErrorHander.java + * 包名:com.ruansee.sx.xayss.p.request.HttpErrorHander + * 当前修改时间:2023年07月04日 16:52:58 + * 上次修改时间:2023年07月04日 16:52:58 + * Copyright©:2023 安徽软思信息技术有限公司 + * 功能描述: + */ + +import com.google.gson.JsonParseException; +import com.rs.macall.androidx.basemodel.utils.LogUtils; + +import org.json.JSONException; + +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; +import java.text.ParseException; + +import retrofit2.HttpException; + +public class HttpErrorHandler { + private static final int UNAUTHORIZED = 401; + private static final int FORBIDDEN = 403; + private static final int NOT_FOUND = 404; + private static final int REQUEST_TIMEOUT = 408; + private static final int INTERNAL_SERVER_ERROR = 500; + private static final int BAD_GATEWAY = 502; + private static final int SERVICE_UNAVAILABLE = 503; + private static final int GATEWAY_TIMEOUT = 504; + + /** + * 统一处理Throwable + * @param e e + * @return msg + */ + public static String requestHandle(Throwable e) { + String msg; + e.printStackTrace(); + if (e instanceof HttpException) { + HttpException httpException = (HttpException) e; + switch (httpException.code()) { + case UNAUTHORIZED: + case FORBIDDEN: + case NOT_FOUND: + case REQUEST_TIMEOUT: + case GATEWAY_TIMEOUT: + case INTERNAL_SERVER_ERROR: + case BAD_GATEWAY: + case SERVICE_UNAVAILABLE: + default: + msg = httpException.code()+"服务器错误"; + break; + } + } else if (e instanceof JsonParseException || e instanceof JSONException + || e instanceof ParseException) { + msg = "数据解析异常"; + } else if (e instanceof ConnectException || e instanceof SocketTimeoutException + || e instanceof UnknownHostException) { + msg = "连接失败,请检查网络"; + } else if (e instanceof NumberFormatException){ + msg = "数字格式化异常"; + } else { + msg = e.getMessage(); + } + LogUtils.e("Request failure",msg); + return msg; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/request/LoadAppCenterImage.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/LoadAppCenterImage.java new file mode 100644 index 0000000..4996652 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/LoadAppCenterImage.java @@ -0,0 +1,215 @@ +package com.ycgis.macall.personalcenter.p.request; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Handler; +import android.os.Message; +import android.widget.ImageView; + +import com.rs.macall.androidx.basemodel.request.OkHttpUtils; +import com.rs.macall.androidx.basemodel.request.RequestCode; +import com.rs.macall.androidx.basemodel.utils.BitMapUtils; +import com.ycgis.macall.personalcenter.p.callback.ImageCallBack; +import com.ycgis.macall.personalcenter.p.request.AsyncBitmapLoader; +import com.ycgis.macall.personalcenter.util.AppTools; +import com.ycgis.macall.personalcenter.util.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.lang.ref.SoftReference; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.FormBody; +import okhttp3.Request; +import okhttp3.Response; +import top.zibin.luban.OnCompressListener; + +/** + * created by: Macall + * create time: 2023/11/16 9:45 + * copyright: @ruansee.com + * Describe: + */ +public class LoadAppCenterImage { + + /** + * 内存图片软引用缓冲 + */ + private HashMap> imageCache = null; +// private File files; + + public LoadAppCenterImage() { + imageCache = new HashMap>(); + } + + public Bitmap loadBitmapText(final Context context, final ImageView imageView, final String imageName, final ImageCallBack imageCallBack) { + //在内存缓存中,则返回Bitmap对象 + if (imageCache.containsKey(imageName)) { + SoftReference reference = imageCache.get(imageName); + Bitmap bitmap = reference.get(); + if (bitmap != null) { + return bitmap; + } + } else { + File cacheDir = new File(FileUtils.IMAGE_DIR + imageName); + if (cacheDir.exists()) { + try { + return BitmapFactory.decodeFile(cacheDir.getAbsolutePath()); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + @SuppressLint("HandlerLeak") final Handler handler = new Handler() { + /* (non-Javadoc) + * @see android.os.Handler#handleMessage(android.os.Message) + */ + @Override + public void handleMessage(final Message msg) { + // TODO Auto-generated method stub + switch (msg.what) { + case -2001: + imageCallBack.imageLoadError(imageView, (String) msg.obj); + break; + case RequestCode.REQUEST_OK: + Bitmap bitmap = (Bitmap) msg.obj; + String wei = imageName.substring(imageName.lastIndexOf(".")); + String lswn = System.currentTimeMillis() + "" + new Random().nextInt(10) + wei; + File files = BitMapUtils.saveBitmap(FileUtils.IMAGE_DIR, lswn, bitmap); + if (files == null || !files.exists()) { + imageCallBack.imageLoadError(imageView, "图片加载失败!"); + return; + } +// String fileName = imageURL.substring(imageURL.lastIndexOf("/") + 1); + ys(context, files, imageName, this); + break; + case 1414: + Bitmap bitmap1 = (Bitmap) msg.obj; + imageCallBack.imageLoad(imageView, bitmap1); + imageCache.put(imageName, new SoftReference(bitmap1)); + break; + case -2121: + imageCallBack.imageLoadError(imageView, (String) msg.obj); + break; + } + } + }; + + Map param = new HashMap<>(); + param.put("devCode", "442eab382e6a49649e3402115bd8837f"); + param.put("appId", AppTools.getPackageName(context)); + param.put("fileId", imageName); + //如果不在内存缓存中,也不在本地(被jvm回收掉),则开启线程下载图片 + postGetPhoto("http://20.90.1.128:7310/api/v1/appInfo/downloadImg", param, handler); +// BaseRequest.postRequestPhotoText("http://20.90.1.128:7310/api/v1/appInfo/downloadImg", param, handler); + } + return null; + } + + private void ys(Context context, File files, final String newFileName, final Handler handler) { + BitMapUtils.lubanCompress(context, files, FileUtils.IMAGE_DIR, new OnCompressListener() { + @Override + public void onStart() { + + } + + @Override + public void onSuccess(File file) { + if (!files.getName().equals(file.getName())) + files.delete(); + boolean is = FileUtils.renameFile(FileUtils.IMAGE_DIR, file.getName(), newFileName); + if (is) { + Bitmap bitmap1 = BitmapFactory.decodeFile(FileUtils.IMAGE_DIR + newFileName); + Message message = handler.obtainMessage(1414, bitmap1); + handler.sendMessage(message); + } + } + + @Override + public void onError(Throwable e) { + Message message = handler.obtainMessage(-2121, "图片加载失败!"); + handler.sendMessage(message); + } + }); + } + + private static FormBody getRequestParam(Map map) { + FormBody.Builder formBody = new FormBody.Builder(); + if (map == null || map.isEmpty()) return formBody.build(); + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() == null) { + formBody.add(entry.getKey(), ""); + } else { + formBody.add(entry.getKey(), entry.getValue()); + } + } + return formBody.build(); + } + + /** + * GET 方式请求数据 图片 + */ + public static void postGetPhoto(String urlTal, Map param, final Handler handler) { + URL url = null; + try { + url = new URL(urlTal); + } catch (MalformedURLException e) { + e.printStackTrace(); + Message message = handler.obtainMessage(); + message.what = -2001; + message.arg2 = 205; + message.obj = "URL错误"; + handler.sendMessage(message); + return; + } + FormBody requestParam = getRequestParam(param); + Request.Builder builder = new Request.Builder() + .url(url); + if (requestParam != null) { + builder.post(requestParam); + } + Request request = builder.build(); + OkHttpUtils.getUploadPhotoClient(10, 30, 40) + .newCall(request) + .enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + System.out.println("加载图片错误:" + e.getMessage()); + Message message = handler.obtainMessage(); + message.what = -2001; + message.arg2 = 205; + message.obj = "加载图片失败:请检查网络连接状况"; + handler.sendMessage(message); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + int responseCode = response.code(); + if (responseCode != 200) { + System.out.println("加载图片错误:请求码错误"); + Message message = handler.obtainMessage(); + message.what = -2001; + message.arg2 = 205; + message.obj = "加载图片失败,请联系管理员"; + handler.sendMessage(message); + return; + } + byte[] photoByte = response.body().bytes(); + Message message = new Message(); + message.what = 200; + message.arg2 = 205; + message.obj = BitmapFactory.decodeByteArray(photoByte, 0, photoByte.length); + handler.sendMessage(message); + } + }); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/request/LoadPhotoImage.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/LoadPhotoImage.java new file mode 100644 index 0000000..c31de38 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/LoadPhotoImage.java @@ -0,0 +1,134 @@ +package com.ycgis.macall.personalcenter.p.request; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.widget.ImageView; + +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.utils.BitMapUtils; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.callback.ImageCallBack; +import com.ycgis.macall.personalcenter.util.FileUtils; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.ref.SoftReference; +import java.util.HashMap; +import java.util.Map; + +import okhttp3.ResponseBody; + +/** + * created by: Macall + * create time: 2023/11/28 14:21 + * copyright: @ruansee.com + * Describe: + */ +public class LoadPhotoImage { + /** + * 内存图片软引用缓冲 + */ + private HashMap> imageCache = null; + + public LoadPhotoImage() { + imageCache = new HashMap>(); + } + + public Bitmap loadPhotoImage(String id, ImageView view, ImageCallBack callBack) { + //在内存缓存中,则返回Bitmap对象 + if (imageCache.containsKey(id)) { + SoftReference reference = imageCache.get(id); + Bitmap bitmap = reference.get(); + if (bitmap != null) { + return bitmap; + } + } else { + File cacheDir = new File(FileUtils.IMAGE_DIR + id); + if (cacheDir.exists()) { + try { + return BitmapFactory.decodeFile(cacheDir.getAbsolutePath()); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + Map param = new HashMap<>(); + param.put("id", id); + param.put("token", RuanseeApplication.getAppCache().getToken()); + param.put("clientType", "MOBILE"); + param.put("imsi1", StringUtil.get(RuanseeApplication.getAppCache().getImsi(),"")); + param.put("deviceFlags",StringUtil.get( RuanseeApplication.getAppCache().getImei(),"")); + param.put("sysCode", RuanseeApplication.getAppCache().getSysmCode()); + ApiModel.request(RetrofitService.getBaseInstance().loadPhoto("http://20.90.2.2/UniAuth/api/sso/v1/download", param), + new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(msg); + if (callBack != null) { + callBack.imageLoadError(view, msg); + } + } + + @Override + public void onRequestSuccess(ResponseBody result) { + InputStream is = null; + byte[] buf = new byte[2048]; + int len = 0; + FileOutputStream fos = null; + // 储存下载文件的目录 + String savePath = FileUtils.IMAGE_DIR; + try { + is = result.byteStream(); +// long total = result.contentLength(); + String nameFromUrl = (String) getPayloads().get(0); +// if (StringUtil.isNullOrEmpty(nameFromUrl)){ +// nameFromUrl = getNameFromUrl(url); +// } + File file = new File(savePath, nameFromUrl); + fos = new FileOutputStream(file); +// long sum = 0; + while ((len = is.read(buf)) != -1) { + fos.write(buf, 0, len); +// sum += len; +// int progress = (int) (sum * 1.0f / total * 100); + // 下载中 +// listener.onDownloading(progress); + } + fos.flush(); + if (callBack != null) { + callBack.imageLoad(view,BitmapFactory.decodeFile(file.getAbsolutePath())); + } + // 下载完成 +// listener.onDownloadSuccess(file); + } catch (Exception e) { + e.printStackTrace(); + if (callBack != null) { + callBack.imageLoadError(view, e.getMessage()); + } + } finally { + try { + if (is != null) + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + if (fos != null) + fos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + }.addPayload(id)); + + return null; + } + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/request/MediaTypeUtils.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/MediaTypeUtils.java new file mode 100644 index 0000000..70a6eee --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/MediaTypeUtils.java @@ -0,0 +1,37 @@ +package com.ycgis.macall.personalcenter.p.request; + +import okhttp3.MediaType; + +/** + * created by: Macall + * create time: 2023/11/23 9:52 + * copyright: @ruansee.com + * Describe: + */ +public class MediaTypeUtils { + + public static MediaType getMediaType(String fileName) { + MediaType mediaType = MediaType.parse("application/octet-stream"); + if (fileName.endsWith(".jpg")) { + mediaType = MediaType.parse("image/jpg"); + } else if (fileName.endsWith(".png")) { + mediaType = MediaType.parse("image/png"); + } else if (fileName.endsWith(".jpeg")) { + mediaType = MediaType.parse("image/jpeg"); + } else if (fileName.endsWith(".mp4")) { + mediaType = MediaType.parse("video/mp4"); + } else if (fileName.endsWith(".mp3")) { + mediaType = MediaType.parse("audio/mpeg"); + } else if (fileName.endsWith(".json")) { + mediaType = MediaType.parse("application/json"); + } else if (fileName.endsWith(".jar")) { + mediaType = MediaType.parse("application/java-archive"); + } else if (fileName.endsWith(".html")) { + mediaType = MediaType.parse("text/html"); + } else if (fileName.endsWith(".gif")) { + mediaType = MediaType.parse("image/gif"); + } + return mediaType; + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/request/MyFunction.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/MyFunction.java new file mode 100644 index 0000000..9a4f606 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/MyFunction.java @@ -0,0 +1,21 @@ +package com.ycgis.macall.personalcenter.p.request; + +import io.reactivex.functions.Function; + +/** + * created by: Macall + * create time: 2023/2/20 10:48 + * copyright: @ruansee.com + * Describe: + */ +public abstract class MyFunction implements Function { + // 设置变量 + // 可重试次数 + protected int maxConnectCount = 2; + // 当前已重试次数 + protected int currentRetryCount = 0; + // 重试等待时间 + protected int waitRetryTime = 0; + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/request/RetrofitApi.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/RetrofitApi.java new file mode 100644 index 0000000..6319c1e --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/RetrofitApi.java @@ -0,0 +1,267 @@ +package com.ycgis.macall.personalcenter.p.request; + +import com.google.gson.JsonObject; +import com.ycgis.macall.personalcenter.m.adapterbean.AppInfoBean; +import com.ycgis.macall.personalcenter.m.adapterbean.FeedbackBean; +import com.ycgis.macall.personalcenter.m.adapterbean.MessageBean; +import com.ycgis.macall.personalcenter.m.requestbean.BaseRequestModel; +import com.ycgis.macall.personalcenter.m.requestbean.FrequentlyBean; +import com.ycgis.macall.personalcenter.m.requestbean.GetDeptNameResult; +import com.ycgis.macall.personalcenter.m.requestbean.HomeBannerBean; +import com.ycgis.macall.personalcenter.m.requestbean.PagingModel; +import com.ycgis.macall.personalcenter.m.requestbean.WorkbenchModel; + +import java.util.List; +import java.util.Map; + +import io.reactivex.Observable; +import okhttp3.RequestBody; +import okhttp3.ResponseBody; +import retrofit2.http.Body; +import retrofit2.http.Field; +import retrofit2.http.FieldMap; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.HeaderMap; +import retrofit2.http.POST; +import retrofit2.http.Query; +import retrofit2.http.QueryMap; +import retrofit2.http.Url; + +/** + * @Describe Api 接口管理 + * 备注 + */ +public interface RetrofitApi { +// public final String baseJd = ""; + + /** + * 获取常见问题 + */ + @GET("app/v1/question") + Observable>> getQuestion(); + + //获取热门城市、轨迹 + //http://192.168.0.109:8081/app/v1/reimburse/getPopularCity?userId=123 + @GET("app/v1/reimburse/getPopularCity") + Observable getPopularCity(@Query("userId") String userId); + + //城市报销标准 + //http://192.168.0.109:8081/app/v1/reimburse/getMoney?userId=123&city=%E4%B8%8A%E6%B5%B7&level=2 + @GET("app/v1/reimburse/getMoney") + Observable getMoneyCity(@Query("userId") String userId,@Query("city") String city,@Query("level") String level); + + //城市报销标准 + //http://192.168.0.109:8081/app/v1/reimburse/getCity?city=bd + @GET("app/v1/reimburse/getCity") + Observable getSearchCity(@Query("city") String cityName); + + //城市报销标准 + //http://192.168.0.109:8081/app/v1/reimburse/getCity?city=bd + @GET("app/v1/zamh/deptList") + Observable getDeptList(@Query("deptName") String deptName,@Query("page") Integer page, @Query("pageSize") Integer pageSize); + +// app/v1/zamh/deptList?deptName=安徽&page=1&pageSize=3 + + /** + * 获取登录方式 + * http://20.90.2.2/UniAuth/api/sso/v1/verifyBind + */ + @FormUrlEncoded + @POST() + Observable getLoginType(@Url String url,@FieldMap Map param); + + @FormUrlEncoded + @POST() + Observable loadPhoto(@Url String url,@FieldMap Map param); + + /** + * 添加第三方应用操作日志 + */ + @POST() + Observable saveAppOperationLog(@Url String url,@Body RequestBody body); + + /** + * 添加第三方应用操作日志 + */ + @POST("app/v1/zamh/addOperationRecords") + Observable saveAppOperationLog(@Body RequestBody body); + + /** + * 获取所属地市 + */ + @GET() + Observable> getDeptName(@Url String url,@Query("deptId") String deptId); + + /** + * 非分页获取应用列表 + * @param deptCode + * @param appName + * @return + */ + @GET("app/v1/zamh/applicationList") + Observable>> applicationList(@Query("name") String appName, @Query("cityNumber") String deptCode, @Query("attribution") Integer attribution); + + /** + * 增加应用点击次数 + * @param applicationId 应用ID + */ + @FormUrlEncoded + @POST("app/v1/zamh/addClickCount") + Observable addClickCount(@Field("applicationId") long applicationId ); + + /** + * + */ + @GET("app/v1/zamh/recommendApplication") + Observable recommendApplication( ); + + @GET("app/v1/zamh/getAllApplicationPage") + Observable>> selectAppList(@Query("name") String appName,@Query("page") Integer page, @Query("pageSize") Integer pageSize); + + /** + * 分页获取应用列表 + * @param cityNumber + * @param page + * @param pageSize + * @param appName + * @return + */ + @GET("app/v1/zamh/applicationPage") + Observable>> applicationPage( @Query("cityNumber") String cityNumber, @Query("page") Integer page, @Query("pageSize") Integer pageSize, @Query("name") String appName, @Query("attribution") Integer attribution); + /** + * 分页获取应用列表 + * @param page + * @param pageSize + * @return + */ + @GET("app/v1/zamh/getWorkbenchApplication") + Observable> getWorkbenchApplication(@Query("page") Integer page, @Query("pageSize") Integer pageSize); + + + /** + * 获取有操作手册的列表 + * @param appName qpp名称用于检索应用 + * @param cityNumber 机构编码 + * @param page 分页页码 + * @param pageSize 每页长度 + */ + @GET("app/v1/zamh/applicationHaveOperationGuide") + Observable>> applicationCzsc(@Query("name") String appName,@Query("cityNumber") String cityNumber,@Query("page") Integer page,@Query("pageSize") Integer pageSize); + + /** + * 根据ID获取操作手册列表 + */ + @GET("app/v1/zamh/operationGuideList") + Observable operationGuideList(@Query("applicationId") String appId); + /** + * 获取轮播图列表 + */ + @GET("app/v1/zamh/pictureList") + Observable>> getBannerList(); + + /** + * 添加反馈 + */ + @POST("app/v1/zamh/addFeedBack") + Observable addFeedBack(@Body RequestBody body); + + /** + * 添加反馈 + */ + @GET("app/v1/zamh/feedbackList") + Observable>> feedbackList(@Query("page") Integer page, @Query("pageSize") Integer pageSize); + + + /** + * 获取消息列表 + */ + @GET("app/v1/zamh/getMessage") + Observable>> getMessage(@Query("state") Integer state, @Query("page") Integer page, @Query("pageSize") Integer pageSize); + + /** + * 设置消息状态为已读 + */ + @GET("app/v1/zamh/readMessage") + Observable readMessage(@Query("id") String id); + + /** + * 设置消息状态为已读 + */ + @GET("tztb/list") + Observable getNews(@Query("page") Integer page,@Query("pageSize") Integer pageSize); + + /** + * 查询人员 + */ + @GET("phone/person/checkPersonBySFZ") + Observable querySfzh(@QueryMap Map param); + + /** + * 查询车辆 + */ + @GET("phone/car/checkCar") + Observable queryCar(@QueryMap Map param); + + /** + * 根据警种搜索 + * 警察 + * @see + */ + @GET("app/v1/zamh/recommendApplicationByPoliceRole") + Observable recommendApplicationByPoliceRole(@Query("role") String role,@Query("applicationName")String applicationName); + + @POST("phone/car/saveCheckCarHistory") + Observable saveCheckCarHistory(@Body RequestBody body); + + /** + * 查询 =通讯录 + */ + @GET("zatxl/list") + Observable getTxlData(@Query("sjgsdwId") String sjgsdwId,@Query("condition") String condition); + +// @GET() +// Observable getTxlData(@Url String url,@Query("sjgsdwId") String sjgsdwId,@Query("condition") String condition); + + /** + * 获取督办单列表 + */ + @GET() + Observable getDbdList(@Url String url,@Query("gmsfhm") String gmsfhm,@Query("pageNo") String pageNo,@Query("pageSize") String pageSize); + + /** + * 查询督办单详情 + */ + @GET() + Observable getDbdDetails(@Url String url,@Query("gmsfhm") String gmsfhm,@Query("id") String id); + + @GET() + Observable downFile(@Url String url); + + /* 上传操作日志*/ + @POST + Observable uploadOperationLog(@Url String url, @Body RequestBody requestBody); + + // ====================== 应用申请相关 ========================================================= + /** + * 应用申请 + */ + @GET() + Observable applyLogin(@Url String url,@Query("policeNo") String policeNo); + /** + * 应用申请 + */ + @GET() + Observable applyGet(@Url String url,@HeaderMap Map headMap, @QueryMap Map param); + + /* 上传操作日志*/ + @POST + Observable applyPost(@Url String url,@HeaderMap Map headMap, @Body RequestBody requestBody); + + /* 上传操作日志*/ +// @FormUrlEncoded +// @POST +// Observable applyPost(@Url String url, @FieldMap Map paramMap); + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/request/RetrofitService.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/RetrofitService.java new file mode 100644 index 0000000..5c89b46 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/RetrofitService.java @@ -0,0 +1,101 @@ +package com.ycgis.macall.personalcenter.p.request; + +import com.rs.macall.androidx.basemodel.request.OkHttpUtils; +import com.ycgis.macall.personalcenter.m.requestbean.BaseRequestModel; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.request.interceptors.HttpLoggingInterceptor; + +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import okhttp3.ResponseBody; +import retrofit2.Converter; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; + +/** + * @Author macall + * @Create 2019/12/4 0004 + * @Describe + */ +public class RetrofitService { + + private static RetrofitApi retrofitService; + + public static void resetRetrofitApi() { + retrofitService = new Retrofit.Builder() + .baseUrl(RuanseeApplication.getAppCache().getBaseUrlPath()) + .addConverterFactory(new NullOnEmptyConverterFactory())//处理接口返回没有响应体body + // 添加Gson转换器 + .addConverterFactory(GsonConverterFactory.create()) +// .addConverterFactory(GsonConverterFactory.create(new GsonBuilder() +// .setLenient() +// .create() +// )) + // 添加Retrofit到RxJava的转换器 + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) + .client(OkHttpUtils.getClient(10, 10, 10,new HttpLoggingInterceptor())) + .build() + .create( + RetrofitApi.class); + } + +// private void init(){ +// retrofitService = new Retrofit.Builder() +// .baseUrl(RuanseeApplication.getAppCache().getBaseUrlPath()) +// .addConverterFactory(new NullOnEmptyConverterFactory())//处理接口返回没有响应体body +// // 添加Gson转换器 +// .addConverterFactory(GsonConverterFactory.create()) +//// .addConverterFactory(GsonConverterFactory.create(new GsonBuilder() +//// .setLenient() +//// .create() +//// )) +// // 添加Retrofit到RxJava的转换器 +// .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) +// .client(OkHttpUtils.getClient(10, 10, 10)) +// .build() +// .create(RetrofitApi.class); +// } + + + //获得RetrofitService对象 + public static RetrofitApi getBaseInstance() { + try { + if (retrofitService == null) { + resetRetrofitApi(); + } + } catch (Exception e) { + e.printStackTrace(); + resetRetrofitApi(); + } + return retrofitService; + } + + public static class NullOnEmptyConverterFactory extends Converter.Factory { + + @Override + public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { + final Converter delegate = retrofit.nextResponseBodyConverter(this, type, annotations); + return new Converter() { + @Override + public Object convert(ResponseBody body) throws IOException { + if (body.contentLength() == 0) { + if (type == BaseRequestModel.class) { + BaseRequestModel baseRequestModel = new BaseRequestModel() { + }; + baseRequestModel.setCode(-1); + baseRequestModel.setMsg("未知错误!"); + return baseRequestModel; + } + return null; + } + return delegate.convert(body); + } + }; + } + } + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/request/UploadProgressResponsBody.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/UploadProgressResponsBody.java new file mode 100644 index 0000000..4d9b357 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/UploadProgressResponsBody.java @@ -0,0 +1,52 @@ +package com.ycgis.macall.personalcenter.p.request; + + + +import com.ycgis.macall.personalcenter.p.callback.UploadProgressListener; + +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; + +import okhttp3.MediaType; +import okhttp3.RequestBody; +import okio.Buffer; +import okio.BufferedSink; +import okio.Okio; +import okio.Source; + +/** + * Created by macall on 2018-06-06. + * copyright:ycgis + */ +public class UploadProgressResponsBody { + + public static RequestBody createCustomRequestBody(final MediaType contentType, final File file, final UploadProgressListener listener) { + return new RequestBody() { + @Override public MediaType contentType() { + return contentType; + } + + @Override public long contentLength() { + return file.length(); + } + + @Override public void writeTo(@NotNull BufferedSink sink) throws IOException { + Source source; + try { + source = Okio.source(file); + Buffer buf = new Buffer(); + long remaining = contentLength(); + for (long readCount; (readCount = source.read(buf, 2048)) != -1; ) { + sink.write(buf, readCount); + listener.onUploadProgress(contentLength(), remaining -= readCount, remaining == 0); + } + listener.onUploadDone(remaining); + } catch (Exception e) { + e.printStackTrace(); + } + } + }; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/request/interceptors/HttpLoggingInterceptor.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/interceptors/HttpLoggingInterceptor.java new file mode 100644 index 0000000..1ad1f58 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/request/interceptors/HttpLoggingInterceptor.java @@ -0,0 +1,306 @@ +package com.ycgis.macall.personalcenter.p.request.interceptors; + +import android.net.Uri; + +import androidx.annotation.NonNull; + +import com.base.code.binary.Base64; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; + +import java.io.EOFException; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import okhttp3.Connection; +import okhttp3.Headers; +import okhttp3.Interceptor; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okhttp3.ResponseBody; +import okhttp3.internal.http.HttpHeaders; +import okhttp3.internal.platform.Platform; +import okio.Buffer; +import okio.BufferedSource; + +import static okhttp3.internal.platform.Platform.INFO; + +public class HttpLoggingInterceptor implements Interceptor { + + private static final Charset UTF8 = Charset.forName("UTF-8"); + + private Map headers; + + public enum Level { + /** + * No logs. + */ + NONE, + /** + * Logs request and response lines. + * + *

Example: + *

{@code
+         * --> POST /greeting http/ic_btn_compare_mode.ic_btn_compare_mode (ic_tv_left_house-byte body)
+         *
+         * <-- 200 OK (22ms, 6-byte body)
+         * }
+ */ + BASIC, + /** + * Logs request and response lines and their respective headers. + * + *

Example: + *

{@code
+         * --> POST /greeting http/ic_btn_compare_mode.ic_btn_compare_mode
+         * Host: example.com
+         * Content-Type: plain/text
+         * Content-Length: ic_tv_left_house
+         * --> END POST
+         *
+         * <-- 200 OK (22ms)
+         * Content-Type: plain/text
+         * Content-Length: 6
+         * <-- END HTTP
+         * }
+ */ + HEADERS, + /** + * Logs request and response lines and their respective headers and bodies (if present). + * + *

Example: + *

{@code
+         * --> POST /greeting http/ic_btn_compare_mode.ic_btn_compare_mode
+         * Host: example.com
+         * Content-Type: plain/text
+         * Content-Length: ic_tv_left_house
+         *
+         * Hi?
+         * --> END POST
+         *
+         * <-- 200 OK (22ms)
+         * Content-Type: plain/text
+         * Content-Length: 6
+         *
+         * Hello!
+         * <-- END HTTP
+         * }
+ */ + BODY + } + + public interface Logger { + void log(String message); + + /** + * + */ + Logger DEFAULT = new Logger() { + @Override + public void log(String message) { + Platform.get().log(message, INFO, null); + } + }; + } + + public HttpLoggingInterceptor() { + this(Logger.DEFAULT); + } + + /** + * 设置请求Header + * + * @param headers header 集合 + */ + public HttpLoggingInterceptor(Map headers) { + this(Logger.DEFAULT); + this.headers = headers; + } + + public HttpLoggingInterceptor(Logger logger) { + this.logger = logger; + } + + private final Logger logger; + private volatile Level level = Level.BODY; + + private void log(String msg){ + if (RuanseeApplication.isPrintLog){ + logger.log(msg); + } + } + + @NonNull + @Override + public Response intercept(@NonNull Chain chain) throws IOException { + // 在这里设置公共的Header + Request requestS = chain.request(); + Request.Builder requestBuilder = requestS.newBuilder(); +// if (StringUtil.hasContent(RuanseeApplication.getAppCache().getSystem_token())) { +// String heard = "Bearer " + RuanseeApplication.getAppCache().getSystem_token(); +// } + if (StringUtil.isNullOrEmpty(RuanseeApplication.getAppCache().getUserInfo())){ + String s = Base64.encodeBase64String(RuanseeApplication.getUserData().toJson().getBytes()); + RuanseeApplication.getAppCache().setUserInfo(s); + } + requestBuilder.addHeader("userInfo", RuanseeApplication.getAppCache().getUserInfo()); + String se = requestS.url().toString(); +// if (StringUtil.hasContent(se)) { +// if (!se.endsWith(".jpg") && !se.endsWith(".png")&&!se.contains("wzt")){ +// se = se.replace("http://" + RuanseeApplication.getAppCache().getIp() + ":8081/", RuanseeApplication.getAppCache().getBaseUrlPath()); +// } +// if (!se.endsWith(".jpg") && !se.endsWith(".png")&&!se.contains("wzt_api_out")){ +// se = se.replace("http://" + RuanseeApplication.getAppCache().getIp() + "/", RuanseeApplication.getAppCache().getBaseUrlPath()); +// } +// requestBuilder.url(se); +// } + //在这里设置公共的Header + Level level = this.level; + + Request request = requestBuilder.build(); + +// Request request = chain.request(); + if (level == Level.NONE) { + return chain.proceed(request); + } + + boolean logBody = level == Level.BODY; + boolean logHeaders = logBody || level == Level.HEADERS; + + RequestBody requestBody = request.body(); + boolean hasRequestBody = requestBody != null; + + Connection connection = chain.connection(); + String requestStartMessage = "--> " + + request.method() + + ' ' + request.url() + + (connection != null ? " " + connection.protocol() : ""); + if (!logHeaders && hasRequestBody) { + requestStartMessage += " (" + requestBody.contentLength() + "-byte body)"; + } + log(requestStartMessage); + + if (logHeaders) { + if (hasRequestBody) { + // Request body headers are only present when installed as a network interceptor. Force + // them to be included (when available) so there values are known. + if (requestBody.contentType() != null) { + log("Content-Type: " + requestBody.contentType()); + } + if (requestBody.contentLength() != -1) { + log("Content-Length: " + requestBody.contentLength()); + } + } + + Headers headers = request.headers(); + for (int i = 0, count = headers.size(); i < count; i++) { + log("Headers.name: " + headers.name(i) + ", Header.value: " + headers.value(i)); + } + + if (!logBody || !hasRequestBody) { + log("--> END " + request.method()); + } else if (bodyEncoded(request.headers())) { + log("--> END " + request.method() + " (encoded body omitted)"); + } else { + Buffer buffer = new Buffer(); + requestBody.writeTo(buffer); + + Charset charset = UTF8; + MediaType contentType = requestBody.contentType(); + if (contentType != null) { + charset = contentType.charset(UTF8); + } + + log(""); + if (isPlaintext(buffer)) { + log(buffer.readString(charset)); + log("--> END " + request.method() + + " (" + requestBody.contentLength() + "-byte body)"); + } else { + log("--> END " + request.method() + " (binary " + + requestBody.contentLength() + "-byte body omitted)"); + } + } + } + + long startNs = System.nanoTime(); + Response response; + try { + response = chain.proceed(request); + } catch (Exception e) { + log("<-- HTTP FAILED: " + e); + throw e; + } + long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs); + + ResponseBody responseBody = response.body(); + long contentLength = responseBody.contentLength(); + String bodySize = contentLength != -1 ? contentLength + "-byte" : "unknown-length"; + log("<-- response.code->" + + response.code() + + (response.message().isEmpty() ? "" : ' ' + response.message()) + + ' ' + response.request().url() + + " (" + tookMs + "ms" + (!logHeaders ? ", " + bodySize + " body" : "") + ')'); + + if (logHeaders) { + Headers headers = response.headers(); + for (int i = 0, count = headers.size(); i < count; i++) { + log("Headers: " + headers.name(i) + " = " + Uri.decode(headers.value(i))); + } + if (!logBody || !HttpHeaders.hasBody(response)) { + log("<-- END HTTP"); + } else if (bodyEncoded(response.headers())) { + log("<-- END HTTP (encoded body omitted)"); + } else { + BufferedSource source = responseBody.source(); + source.request(Long.MAX_VALUE); // Buffer the entire body. + Buffer buffer = source.buffer(); + Charset charset = UTF8; + MediaType contentType = responseBody.contentType(); + if (contentType != null) { + charset = contentType.charset(UTF8); + } + if (!isPlaintext(buffer)) { + log(""); + log("<-- END HTTP (binary " + buffer.size() + "-byte body omitted)"); + return response; + } + if (contentLength != 0) { + log(""); + log(buffer.clone().readString(charset)); + } + log("<-- END HTTP (" + buffer.size() + "-byte body)"); + } + } + return response; + } + + private static boolean isPlaintext(Buffer buffer) { + try { + Buffer prefix = new Buffer(); + long byteCount = buffer.size() < 64 ? buffer.size() : 64; + buffer.copyTo(prefix, 0, byteCount); + for (int i = 0; i < 16; i++) { + if (prefix.exhausted()) { + break; + } + int codePoint = prefix.readUtf8CodePoint(); + if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) { + return false; + } + } + return true; + } catch (EOFException e) { + return false; // Truncated UTF-8 sequence. + } + } + + private boolean bodyEncoded(Headers headers) { + String contentEncoding = headers.get("Content-Encoding"); + return contentEncoding != null && !contentEncoding.equalsIgnoreCase("identity"); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/rxjava/ResultObserver.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/rxjava/ResultObserver.java new file mode 100644 index 0000000..c0be3c4 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/rxjava/ResultObserver.java @@ -0,0 +1,53 @@ +package com.ycgis.macall.personalcenter.p.rxjava; + +import org.jetbrains.annotations.NotNull; + +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; + +/** + * created by: Macall + * create time: 2023/11/20 14:21 + * copyright: @ruansee.com + * Describe: + */ +public abstract class ResultObserver implements Observer { + private String identifierKey; + + public ResultObserver(String identifierKey) { + this.identifierKey = identifierKey; + } + + protected abstract void onNext(String identifierKey,@NotNull T data); + + protected void onSubscribe(String identifierKey, @NotNull Disposable d) { + + } + protected void onError(String identifierKey, @NotNull Throwable data){ + + } + protected void onComplete(String identifierKey){ + + } + + @Override + public void onSubscribe(@NotNull Disposable d) { + onSubscribe(identifierKey,d); + } + + @Override + public void onNext(@NotNull T o) { + onNext(identifierKey,o); + } + + @Override + public void onError(@NotNull Throwable e) { + onError(identifierKey,e); + + } + + @Override + public void onComplete() { + onComplete(identifierKey); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/rxjava/UpdateUiOnSubscribe.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/rxjava/UpdateUiOnSubscribe.java new file mode 100644 index 0000000..8841f2c --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/rxjava/UpdateUiOnSubscribe.java @@ -0,0 +1,33 @@ +package com.ycgis.macall.personalcenter.p.rxjava; + +import org.jetbrains.annotations.NotNull; + +import io.reactivex.ObservableEmitter; +import io.reactivex.ObservableOnSubscribe; + +/** + * created by: Macall + * create time: 2023/11/17 17:17 + * copyright: @ruansee.com + * Describe: + */ +public abstract class UpdateUiOnSubscribe implements ObservableOnSubscribe { + + public E object; + + public UpdateUiOnSubscribe(E object) { + this.object = object; + } + + public UpdateUiOnSubscribe() { + } + + + + public abstract void subscribe(E date, @NotNull ObservableEmitter emitter); + + @Override + public void subscribe(@NotNull ObservableEmitter emitter) throws Exception { + subscribe(object,emitter); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/service/GetMessageService.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/service/GetMessageService.java new file mode 100644 index 0000000..876a417 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/service/GetMessageService.java @@ -0,0 +1,172 @@ +package com.ycgis.macall.personalcenter.p.service; + +import android.annotation.SuppressLint; +import android.app.job.JobInfo; +import android.app.job.JobParameters; +import android.app.job.JobScheduler; +import android.app.job.JobService; +import android.content.ComponentName; +import android.os.Build; + +import androidx.annotation.RequiresApi; + +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.ycgis.macall.personalcenter.m.adapterbean.MessageBean; +import com.ycgis.macall.personalcenter.m.event.MessageEvent; +import com.ycgis.macall.personalcenter.m.requestbean.BaseRequestModel; +import com.ycgis.macall.personalcenter.m.requestbean.PagingModel; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; + +import org.greenrobot.eventbus.EventBus; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/1/3 11:29 + * copyright: @ruansee.com + * Describe: + */ +@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) +public class GetMessageService extends JobService { + private static String TAG = "GetMessageService"; + private JobParameters jobParameters; + + @Override + public boolean onStartJob(JobParameters params) { + jobParameters = params; + getMsg(); + doService(); + return true; + } + + @SuppressLint("MissingPermission") + private void doService() { +// if (!MPush.I.hasStarted()) { + JobScheduler jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE); + JobInfo.Builder builder = new JobInfo.Builder(1, new ComponentName(this, GetMessageService.class)); + if (Build.VERSION.SDK_INT >= 24) { + builder.setMinimumLatency(RuanseeApplication.REFRESH_MESSAGE_TIME); //执行的最小延迟时间 + builder.setOverrideDeadline(RuanseeApplication.REFRESH_MESSAGE_TIME); //执行的最长延时时间 + builder.setBackoffCriteria(RuanseeApplication.REFRESH_MESSAGE_TIME, JobInfo.BACKOFF_POLICY_LINEAR);//线性重试方案 + } else { + builder.setPeriodic(RuanseeApplication.REFRESH_MESSAGE_TIME); + } + builder.setPersisted(true); // 设置设备重启时,执行该任务 + builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); + builder.setRequiresCharging(false);//设置是否在只有插入充电器的时候执行 + builder.setRequiresDeviceIdle(false);//设置手机系统处于空闲状态下执行 + JobInfo info = builder.build(); + jobScheduler.schedule(info); //开始定时执行该系统任务 + +// } + } + + @Override + public boolean onStopJob(JobParameters params) { + return false; + } + + private void getMsg() { + ApiModel.requestIO(RetrofitService.getBaseInstance().getMessage(0, 1, 3), + new BaseRequestCallback>>() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(TAG, msg); + jobFinished(jobParameters, false); + } + + @Override + public void onRequestSuccess(BaseRequestModel> result) { +// LogUtils.w(TAG, result.toString()); + if (result.getCode() == 20041) { + PagingModel data = result.getData(); + int counts = data.getCounts(); + if (counts <= 0) { + jobFinished(jobParameters, false); + return; + } + List items = data.getItems(); + MessageEvent event = new MessageEvent(); + event.setCount(counts); + String title = "全部消息(" + counts + ""; + event.setMsg(title); + // updateWidget(String.format("未读消息%s条", counts)); + int lengthNum = Math.min(items.size(), 3); + List messageBeans = items.subList(0, lengthNum); + for (int i = 0; i < messageBeans.size(); i++) { + MessageBean bean = messageBeans.get(i); + bean.setBaseType(1); + } + if (!messageBeans.isEmpty()) { + event.setMessageBeanList(messageBeans); + EventBus.getDefault().post(event); + } + } + jobFinished(jobParameters, false); + +// List messageBeanList = new ArrayList<>(); +// try { +// JSONObject object = new JSONObject(result.toString()); +// String code = TypConversion.getJsonStr(object, "code"); +// if (code.equals("20041")) { +// JSONObject data = object.getJSONObject("data"); +// int counts = TypConversion.getJsonInt(data, "counts", 0); +// if (counts <= 0) { +//// updateWidget("暂无新消息"); +// jobFinished(jobParameters, false); +// return; +// } +// MessageEvent event = new MessageEvent(); +// event.setCount(counts); +// updateWidget(String.format("未读消息%s条", counts)); +// String title = "全部消息(" + counts + ""; +// event.setMsg(title); +// JSONArray items = data.getJSONArray("items"); +// int lengthNum = Math.min(items.length(), 2); +// for (int i = 0; i < lengthNum; i++) { +// JSONObject jsonObject = TypConversion.getJSONObject(items, i); +// if (jsonObject == null) continue; +// MessageBean bean = new MessageBean(); +// bean.setBaseType(1); +// bean.setAppName(TypConversion.getJsonStr(jsonObject, "appName")); +// bean.setId(TypConversion.getJsonStr(jsonObject, "id")); +// bean.setMsgId(TypConversion.getJsonStr(jsonObject, "msgId")); +// bean.setTitle(TypConversion.getJsonStr(jsonObject, "msgTitle")); +// bean.setContent(TypConversion.getJsonStr(jsonObject, "msgContent")); +// bean.setClientId(TypConversion.getJsonStr(jsonObject, "appId")); +// bean.setClientSecret(TypConversion.getJsonStr(jsonObject, "appSecret")); +// bean.setAppLinkUrl(TypConversion.getJsonStr(jsonObject, "appUrl")); +// bean.setMsgType(TypConversion.getJsonStr(jsonObject, "msgType")); +// bean.setTime(TypConversion.getJsonStr(jsonObject, "sendingTime")); +// int state = TypConversion.getJsonInt(jsonObject, "state", 0); +// bean.setRead(state != 0); +// messageBeanList.add(bean); +// } +// if (!messageBeanList.isEmpty()) { +// event.setMessageBeanList(messageBeanList); +// EventBus.getDefault().post(event); +// } +// jobFinished(jobParameters, false); +// } +// } catch(JSONException e){ +// e.printStackTrace(); +// jobFinished(jobParameters, false); +// } + } + }); + } + + private void updateWidget(String msg) { +// RemoteViews rv = new RemoteViews(this.getPackageName(), R.layout.layout_widget); +// rv.setTextViewText(R.id.tv_msg_count, msg); +// ComponentName cn = new ComponentName(this, ListWidgetProvider.class); +// AppWidgetManager am = AppWidgetManager.getInstance(this); +// am.updateAppWidget(cn, rv); + } + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/p/service/MyService.java b/app/src/main/java/com/ycgis/macall/personalcenter/p/service/MyService.java new file mode 100644 index 0000000..7dc763b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/p/service/MyService.java @@ -0,0 +1,16 @@ +package com.ycgis.macall.personalcenter.p.service; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; + +public class MyService extends Service { + public MyService() { + } + + @Override + public IBinder onBind(Intent intent) { + // TODO: Return the communication channel to the service. + throw new UnsupportedOperationException("Not yet implemented"); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/AhdsAddressUtils.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/AhdsAddressUtils.java new file mode 100644 index 0000000..1e24c61 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/AhdsAddressUtils.java @@ -0,0 +1,43 @@ +package com.ycgis.macall.personalcenter.util; + +import com.rs.macall.androidx.basemodel.utils.StringUtil; + +/** + * created by: Macall + * create time: 2022/12/3 10:25 + * copyright: @ruansee.com + * Describe: 安徽各地市 + */ +public class AhdsAddressUtils { + + private final static String[][] addresss = new String[][]{ + {"省厅","3400"}, + {"合肥","3401"}, + {"芜湖","3402"}, + {"蚌埠","3403"}, + {"淮南","3404"}, + {"马鞍山","3405"}, + {"淮北","3406"}, + {"铜陵","3407"}, + {"安庆","3408"}, + {"黄山","3410"}, + {"滁州","3411"}, + {"阜阳","3412"}, + {"宿州","3413"}, + {"六安","3415"}, + {"亳州","3416"}, + {"池州","3417"}, + {"宣城","3418"} + }; + + public static String getAddressNameByCode(String code){ + if (StringUtil.isNullOrEmpty(code)) return ""; + for (int i = 0; i < addresss.length; i++) { + if (code.startsWith(addresss[i][1])) { + return addresss[i][0]; + } + } + return ""; + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/AppTools.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/AppTools.java new file mode 100644 index 0000000..f3395f6 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/AppTools.java @@ -0,0 +1,300 @@ +/** + * probject:lvxin + * @version 5.0 + * + * @author 3979434@qq.com + */ +package com.ycgis.macall.personalcenter.util; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.graphics.BitmapFactory; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.Environment; +import android.os.StatFs; +import android.text.format.Formatter; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.MeasureSpec; +import android.view.ViewGroup; + +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; + +import java.io.File; +import java.util.List; + +public class AppTools { + + public void measureView(View child) { + ViewGroup.LayoutParams p = child.getLayoutParams(); + if (p == null) { + p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT); + } + int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width); + int lpHeight = p.height; + int childHeightSpec; + if (lpHeight > 0) { + childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, + MeasureSpec.EXACTLY); + } else { + childHeightSpec = MeasureSpec.makeMeasureSpec(0, + MeasureSpec.UNSPECIFIED); + } + child.measure(childWidthSpec, childHeightSpec); + } + + public boolean isSystemApplication(Context context) { + final PackageManager pm = (PackageManager) context.getPackageManager(); + try { + final PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0); + if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) + { + return true; + } + }catch(Exception err) + { + + } + return false; + } + + private final static int kSystemRootStateUnknow = -1; + private final static int kSystemRootStateDisable = 0; + private final static int kSystemRootStateEnable = 1; + private static int systemRootState = kSystemRootStateUnknow; + + public static boolean isRootSystem() { + if (systemRootState == kSystemRootStateEnable) { + return true; + } else if (systemRootState == kSystemRootStateDisable) { + return false; + } + File f = null; + final String kSuSearchPaths[] = { "/system/bin/", "/system/xbin/", + "/system/sbin/", "/sbin/", "/vendor/bin/" }; + try { + for (int i = 0; i < kSuSearchPaths.length; i++) { + f = new File(kSuSearchPaths[i] + "su"); + if (f != null && f.exists()) { + systemRootState = kSystemRootStateEnable; + return true; + } + } + } catch (Exception e) { + } + systemRootState = kSystemRootStateDisable; + return false; + } + + public static boolean netWorkAvailable(Context context) { + try { + ConnectivityManager nw = (ConnectivityManager) context + .getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo networkInfo = nw.getActiveNetworkInfo(); + return networkInfo != null; + + } catch (Exception e) { + // TODO: handle exception + return false; + } + } + + /**根据包名判断某个应用程序是否安装方法*/ + public static boolean isInstall(Context context , String packageName) { + if (packageName == null || "".equals(packageName)) + return false; + try { + ApplicationInfo info = context.getPackageManager().getApplicationInfo( + packageName, PackageManager.GET_UNINSTALLED_PACKAGES); + return true; + } catch (PackageManager.NameNotFoundException e) { + return false; + } + } + + public static boolean startApp(Context context,String appPageName){ + if (StringUtil.isNullOrEmpty(appPageName)){ + ToastUtil.centered(context,"包名错误,请联系管理员!"); + return false; + } + //首先判断调用的apk是否安装 + boolean isAlive = isInstall(context,appPageName); + if(isAlive){ + jumpApp(context,appPageName); + return true; + }else{ + + ToastUtil.centeredLong(context,"应用未安装,请至应用商店下载!"); + return false; + } + } + + /** + * 启动APP + * @param packageName 包名 + */ + public static void jumpApp(Context context,String packageName) { + String className = ""; + Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); + // resolveIntent.addCategory(Constant.CATEGORY_YCGIS_LAUNCHER); + resolveIntent.setPackage(packageName); + // 通过getPackageManager()的queryIntentActivities方法遍历 + List resolveinfoList = context.getPackageManager() + .queryIntentActivities(resolveIntent, 0); + ResolveInfo resolveinfo = resolveinfoList.iterator().next(); + if (resolveinfo != null) { + className = resolveinfo.activityInfo.name; + } else { + + } + Intent intent = new Intent(); + ComponentName component = new ComponentName(packageName, className); + intent.setComponent(component); + context.startActivity(intent); + } + + /** + * 获得SD卡总大小 + * + * @return + */ + public static String getSDTotalSize(Context context) { + File path = Environment.getExternalStorageDirectory(); + StatFs stat = new StatFs(path.getPath()); + long blockSize = stat.getBlockSize(); + long totalBlocks = stat.getBlockCount(); + return Formatter.formatFileSize(context, blockSize * totalBlocks); + } + + /** + * 获得sd卡剩余容量,即可用大小 + * + * @return + */ + public static String getSDAvailableSize(Context context) { + File path = Environment.getExternalStorageDirectory(); + StatFs stat = new StatFs(path.getPath()); + long blockSize = stat.getBlockSize(); + long availableBlocks = stat.getAvailableBlocks(); + return Formatter.formatFileSize(context, blockSize * availableBlocks); + } + + /** + * 获得机身内存总大小 + * + * @return + */ + public static String getRomTotalSize(Context context) { + File path = Environment.getDataDirectory(); + StatFs stat = new StatFs(path.getPath()); + long blockSize = stat.getBlockSize(); + long totalBlocks = stat.getBlockCount(); + return Formatter.formatFileSize(context, blockSize * totalBlocks); + } + + /** + * 获得机身可用内存 + * + * @return + */ + public static String getRomAvailableSize(Context context) { + File path = Environment.getDataDirectory(); + StatFs stat = new StatFs(path.getPath()); + long blockSize = stat.getBlockSize(); + long availableBlocks = stat.getAvailableBlocks(); + return Formatter.formatFileSize(context, blockSize * availableBlocks); + } + + public static boolean contains(int[] loc,MotionEvent event) + { + return event.getY() >= loc[1] && event.getY() <= loc[3] + && event.getX() >= loc[0] && event.getX() <= loc[2]; + } + + + + /** + * compute Sample Size + * + * @param options + * @param minSideLength + * @param maxNumOfPixels + * @return + */ + public static int computeSampleSize(BitmapFactory.Options options, + int minSideLength, int maxNumOfPixels) { + int initialSize = computeInitialSampleSize(options, minSideLength, + maxNumOfPixels); + + int roundedSize; + if (initialSize <= 8) { + roundedSize = 1; + while (roundedSize < initialSize) { + roundedSize <<= 1; + } + } else { + roundedSize = (initialSize + 7) / 8 * 8; + } + + return roundedSize; + } + + /** + * compute Initial Sample Size + * + * @param options + * @param minSideLength + * @param maxNumOfPixels + * @return + */ + private static int computeInitialSampleSize(BitmapFactory.Options options, + int minSideLength, int maxNumOfPixels) { + double w = options.outWidth; + double h = options.outHeight; + + // 上下限范围 + int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math + .sqrt(w * h / maxNumOfPixels)); + int upperBound = (minSideLength == -1) ? 128 : (int) Math.min( + Math.floor(w / minSideLength), Math.floor(h / minSideLength)); + + if (upperBound < lowerBound) { + // return the larger one when there is no overlapping zone. + return lowerBound; + } + + if ((maxNumOfPixels == -1) && (minSideLength == -1)) { + return 1; + } else if (minSideLength == -1) { + return lowerBound; + } else { + return upperBound; + } + } + + /** + * [获取应用程序版本名称信息] + * @param context + * @return 当前应用的版本名称 + */ + public static synchronized String getPackageName(Context context) { + try { + PackageManager packageManager = context.getPackageManager(); + PackageInfo packageInfo = packageManager.getPackageInfo( + context.getPackageName(), 0); + return packageInfo.packageName; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/FileUtils.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/FileUtils.java new file mode 100644 index 0000000..f3ae679 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/FileUtils.java @@ -0,0 +1,514 @@ +package com.ycgis.macall.personalcenter.util; + +import android.annotation.SuppressLint; +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.graphics.Bitmap; +import android.graphics.Matrix; +import android.media.ExifInterface; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.util.Base64; + +import androidx.annotation.IntDef; +import androidx.core.content.FileProvider; + +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.p.callback.SelectReturnCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.text.DecimalFormat; +import java.util.List; + +/** + * created by: Macall + * create time: 2022/10/26 15:09 + * copyright: @ruansee.com + * Describe: + */ +public class FileUtils { + + private static String filePath; + + //文件路径 + public static String FILE_DIR = "file"; + //数据库文件路径 + public static String DB_DIR = "dateBase"; + //图片文件存储路径 + public static String IMAGE_DIR = "Image"; + //视频文件存储路径 + public static String VOID_DIR = "Void"; + //下载文件存储路径 + public static String DOWNLOADS_DIR = "downloads"; + //下载文件存储路径 + public static String LOG_DIR = "Log"; + + /** + * 初始化文件目录,Android10以下可以访问外部存储的任意位置,Android10(包括)以上只能访问指定目录。 + * 为适配Android 10 及以上,应用目录应存储在该目录下 + * + * @param context 上下文环境 + * @return 文件录 + */ + public static String initFilePath(Context context) { + if (StringUtil.isNullOrEmpty(filePath)) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + filePath = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath().replace("Documents", ""); + DOWNLOADS_DIR = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + File.separator; + IMAGE_DIR = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath() + File.separator; + VOID_DIR = context.getExternalFilesDir(Environment.DIRECTORY_DCIM).getAbsolutePath() + File.separator; + FILE_DIR = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + File.separator; + DB_DIR = FILE_DIR + "/dateBase/"; + LOG_DIR = filePath + "log/"; + } else { + // /storage/emulated/0/Android/data/com.spsj.data/files/Documents + filePath = Environment.getExternalStorageDirectory().getPath() + "/Android/data/com.ycgis.macall.personalcenter/"; + DOWNLOADS_DIR = filePath + "Downloads/"; + IMAGE_DIR = filePath + "Pictures/"; + VOID_DIR = filePath + "DCIM/"; + FILE_DIR = filePath + "Documents/"; + DB_DIR = FILE_DIR + "/dateBase/"; + LOG_DIR = filePath + "log/"; + } + } + return filePath; + } + + public static String getPhotoName() { + return System.currentTimeMillis() + ".jpg"; + } + + + /** + * @param context + * @param attrsName + * @param filePath + * @return + */ + public static File copyAPK(Context context, String attrsName, String filePath) { + InputStream is = null; + try { + is = context.getAssets().open(attrsName); + File destFile = new File(filePath, attrsName); + if (destFile.exists()) { + destFile.delete(); + } +// if (!destFile.exists()) { + return copy(is, destFile.getAbsolutePath()); +// } +// return null; + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + public static File copy(InputStream is, String path) { + try { + File file = new File(path); + FileOutputStream fos = new FileOutputStream(file); + + byte[] buffer = new byte[1024]; + int len; + while ((len = is.read(buffer)) != -1) { + fos.write(buffer, 0, len); + } + fos.flush(); + fos.close(); + is.close(); + + return file; + } catch (Exception e) { + e.printStackTrace(); + return null; + + } + } + + /** + * 本地图片转 base64 字符 + * + * @param filePath 图标全路径 + * @return base64 字符 + */ + public static String fileToBase64(String filePath) { + if (StringUtil.isNullOrEmpty(filePath)) return ""; + File f = new File(filePath); + if (!f.exists()) return ""; + InputStream in = null; + byte[] data = null; + try { + in = new FileInputStream(f); + data = new byte[(int) f.length()]; + in.read(data); + in.close(); +// return Base64.encodeBase64String(data); +// return Base64.encodeBase64URLSafeString(data); + return Base64.encodeToString(data, Base64.DEFAULT); + } catch (IOException e) { + e.printStackTrace(); + return ""; + } + } + + public static void deleteFiles(File file) { + if (file == null || !file.exists()) return; + if (file.isDirectory()) { + File[] files = file.listFiles(); + for (int i = 0; i < files.length; i++) { + File file1 = files[i]; + deleteFiles(file1); + } + } else { + file.delete(); + } + } + + public static long calculateFileSize(File file) { + long totals = 0; + if (!file.exists()) return 0; + if (file.isDirectory()) { + File[] files = file.listFiles(); + if (files == null) return 0; + for (File fl : files) { + totals += calculateFileSize(fl); + } + } else { + totals += file.length(); + } + return totals; + } + + /** + * 文件重命名 + * + * @param dir 文件路径 + * @param sourcePath 原文件名 + * @param targetPath 修改后的文件名 + * @return 是否修改成功 + */ + public static boolean renameFile(String dir, String sourcePath, String targetPath) { + File toBeRenamed = new File(dir, sourcePath); + //检查要重命名的文件是否存在,是否是文件 + if (!toBeRenamed.exists() || toBeRenamed.isDirectory()) { + LogUtils.e("FileUtils", "待重命名文件不存在: " + sourcePath); + return false; + } + File newFile = new File(dir, targetPath); + //修改文件名 + return toBeRenamed.renameTo(newFile); + } + + /*打开app*/ + @TargetApi(Build.VERSION_CODES.DONUT) + private void doStartApplicationWithPackageName(Context context, String packagename) { + + // 通过包名获取此APP详细信息,包括Activities、services、versioncode、name等等 + PackageInfo packageinfo = null; + try { + packageinfo = context.getPackageManager().getPackageInfo(packagename, 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (packageinfo == null) { + return; + } + + // 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent + Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); + resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER); + resolveIntent.setPackage(packageinfo.packageName); + + // 通过getPackageManager()的queryIntentActivities方法遍历 + List resolveinfoList = context.getPackageManager() + .queryIntentActivities(resolveIntent, 0); + + ResolveInfo resolveinfo = resolveinfoList.iterator().next(); + if (resolveinfo != null) { + // packagename = 参数packname + String packageName = resolveinfo.activityInfo.packageName; + // 这个就是我们要找的该APP的LAUNCHER的Activity[组织形式:packagename.mainActivityname] + String className = resolveinfo.activityInfo.name; + // LAUNCHER Intent + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + + // 设置ComponentName参数1:packagename参数2:MainActivity路径 + ComponentName cn = new ComponentName(packageName, className); + + intent.setComponent(cn); + context.startActivity(intent); + } + } + + /** + * 文件大小单位 + */ + @IntDef(value = {FileSizeFormType.B, FileSizeFormType.K, FileSizeFormType.M, FileSizeFormType.T}) + @Retention(RetentionPolicy.SOURCE) + public @interface FileSizeFormType { + int B = 0; //bit + int K = 1; //KB + int M = 2; //MB + int T = 3; //TB + } + + /** + * 格式化文件大小 + * + * @param fileSize 文件大小单位 bit + * @param type 格式化单位{@link FileSizeFormType} + * @return 格式化后的大小 + */ + public static String formatFileSize(long fileSize, int type) { + DecimalFormat decimalFormat = new DecimalFormat("#.00"); + if (FileSizeFormType.K == type) { + return decimalFormat.format((double)fileSize / 1024 )+ "K"; + } else if (FileSizeFormType.M == type) { + return decimalFormat.format((double)fileSize / 1024 / 1024 )+ "M"; + } else if (FileSizeFormType.T == type) { + return decimalFormat.format((double)fileSize / 1024 / 1024 / 1024) + "T"; + } + return fileSize + "B"; + } + + /** + * 打开原生APP + * + * @param context + * @param strPackage 包名 + * @param callback + */ + public static void startAPP(Context context, String strPackage, SelectReturnCallback callback) { + try { + // 通过包名获取此APP详细信息,包括Activities、services、versioncode、name等等 + PackageInfo packageinfo = null; + try { + packageinfo = context.getPackageManager().getPackageInfo(strPackage, 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + if (callback != null) { + callback.returnMsg(false); + } + } + if (packageinfo == null) { + if (callback != null) { + callback.returnMsg(false); + } + return; + } + // 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent + Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); + resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER); + resolveIntent.setPackage(packageinfo.packageName); + + // 通过getPackageManager()的queryIntentActivities方法遍历 + List resolveinfoList = context.getPackageManager() + .queryIntentActivities(resolveIntent, 0); + + ResolveInfo resolveinfo = resolveinfoList.iterator().next(); + if (resolveinfo != null) { + // packagename = 参数packname + String packageName = resolveinfo.activityInfo.packageName; + // 这个就是我们要找的该APP的LAUNCHER的Activity[组织形式:packagename.mainActivityname] + String className = resolveinfo.activityInfo.name; + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + //TODO 打开第三方应用 应当设置 启动模式为新的任务栈 + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setClassName(packageName, className); + context.startActivity(intent); + } + ApiModel.uploadOperationLog("3","3","用户跳转到第三方应用:"+strPackage); + } catch (Exception e) { + e.printStackTrace(); + if (callback != null) { + callback.returnMsg(false); + } +// ToastUtil.centered(context, "没有安装应用,请至应用中心下载安装!"); + } + } + + /** + * 根据路径打开文件 + * + * @param context 上下文 + * @param path 文件路径 + */ + public static void openFileByPath(Activity context, String path) { + if (context == null || path == null) return; + File file = new File(path); + if (!file.exists()) { + return; + } + Uri photoURI; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + //如果是7.0及以上的系统使用FileProvider的方式创建一个Uri + LogUtils.e("相机权限", "系统版本大于7.0"); +// String provider = context.getString(MResource.getIdByName(context.getApplication(), "string", "app_file_provider_authority")); + photoURI = FileProvider.getUriForFile(context, context.getString(R.string.fileProviderName), file); + } else { + //7.0以下使用这种方式创建一个Uri + photoURI = Uri.fromFile(file); + } + Intent intent = new Intent(); + //设置intent的Action属性 + intent.setAction(Intent.ACTION_VIEW); + //文件的类型 + intent.addCategory(Intent.CATEGORY_DEFAULT); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + String type = ""; + for (int i = 0; i < MATCH_ARRAY.length; i++) { + //判断文件的格式 + if (path.endsWith(MATCH_ARRAY[i][0])) { + type = MATCH_ARRAY[i][1]; + break; + } + } + try { + //设置intent的data和Type属性 + intent.setDataAndType(photoURI, type); + //跳转 + context.startActivity(intent); + } catch (Exception e) { //当系统没有携带文件打开软件,提示 + ToastUtil.centered(context, "无法打开该格式文件!"); + e.printStackTrace(); + } + } + + //建立一个文件类型与文件后缀名的匹配表 + private static final String[][] MATCH_ARRAY = { + //{后缀名, 文件类型} + {".3gp", "video/3gpp"}, + {".apk", "application/vnd.android.package-archive"}, + {".asf", "video/x-ms-asf"}, + {".avi", "video/x-msvideo"}, + {".bin", "application/octet-stream"}, + {".bmp", "image/bmp"}, + {".c", "text/plain"}, + {".class", "application/octet-stream"}, + {".conf", "text/plain"}, + {".cpp", "text/plain"}, + {".doc", "application/msword"}, + {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}, + {".xls", "application/vnd.ms-excel"}, + {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}, + {".exe", "application/octet-stream"}, + {".gif", "image/gif"}, + {".gtar", "application/x-gtar"}, + {".gz", "application/x-gzip"}, + {".h", "text/plain"}, + {".htm", "text/html"}, + {".html", "text/html"}, + {".jar", "application/java-archive"}, + {".java", "text/plain"}, + {".jpeg", "image/jpeg"}, + {".jpg", "image/jpeg"}, + {".js", "application/x-javascript"}, + {".log", "text/plain"}, + {".m3u", "audio/x-mpegurl"}, + {".m4a", "audio/mp4a-latm"}, + {".m4b", "audio/mp4a-latm"}, + {".m4p", "audio/mp4a-latm"}, + {".m4u", "video/vnd.mpegurl"}, + {".m4v", "video/x-m4v"}, + {".mov", "video/quicktime"}, + {".mp2", "audio/x-mpeg"}, + {".mp3", "audio/x-mpeg"}, + {".mp4", "video/mp4"}, + {".mpc", "application/vnd.mpohun.certificate"}, + {".mpe", "video/mpeg"}, + {".mpeg", "video/mpeg"}, + {".mpg", "video/mpeg"}, + {".mpg4", "video/mp4"}, + {".mpga", "audio/mpeg"}, + {".msg", "application/vnd.ms-outlook"}, + {".ogg", "audio/ogg"}, + {".pdf", "application/pdf"}, + {".png", "image/png"}, + {".pps", "application/vnd.ms-powerpoint"}, + {".ppt", "application/vnd.ms-powerpoint"}, + {".prop", "text/plain"}, + {".rar", "application/x-rar-compressed"}, + {".rc", "text/plain"}, + {".rmvb", "audio/x-pn-realaudio"}, + {".rtf", "application/rtf"}, + {".sh", "text/plain"}, + {".tar", "application/x-tar"}, + {".tgz", "application/x-compressed"}, + {".txt", "text/plain"}, + {".wav", "audio/x-wav"}, + {".wma", "audio/x-ms-wma"}, + {".wmv", "audio/x-ms-wmv"}, + {".wps", "application/vnd.ms-works"}, + {".xml", "text/plain"}, + {".z", "application/x-compress"}, + {".zip", "application/zip"}, + {"", "*/*"} + }; + + /** + * 读取图片属性:旋转的角度 + * + * @param path 图片绝对路径 + * @return degree 旋转角度 + */ + public static int readPictureDegree(String path) { + int degree = 0; + try { + ExifInterface exifInterface = new ExifInterface(path); + int orientation = exifInterface.getAttributeInt( + ExifInterface.TAG_ORIENTATION, + ExifInterface.ORIENTATION_NORMAL); + switch (orientation) { + case ExifInterface.ORIENTATION_ROTATE_90: + degree = 90; + break; + case ExifInterface.ORIENTATION_ROTATE_180: + degree = 180; + break; + case ExifInterface.ORIENTATION_ROTATE_270: + degree = 270; + break; + } + } catch (IOException e) { + e.printStackTrace(); + } + return degree; + } + + /** + * 旋转图片 + * + * @param angle 旋转角度 + * @param bitmap 原图 + * @return bitmap 旋转后的图片 + */ + public static Bitmap rotateImage(int angle, Bitmap bitmap) { + // 图片旋转矩阵 + Matrix matrix = new Matrix(); + matrix.postRotate(angle); + // 得到旋转后的图片 + return Bitmap.createBitmap(bitmap, 0, 0, + bitmap.getWidth(), bitmap.getHeight(), matrix, true); + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/IPAddressUtils.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/IPAddressUtils.java new file mode 100644 index 0000000..63f3519 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/IPAddressUtils.java @@ -0,0 +1,131 @@ +package com.ycgis.macall.personalcenter.util; + +import android.os.Build; +import android.util.Log; + +import com.rs.macall.androidx.basemodel.utils.LogUtils; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.regex.Pattern; + +/** + * created by: Macall + * create time: 2024/1/17 16:55 + * copyright: @ruansee.com + * Describe: + */ +public class IPAddressUtils { + private static final String IPV4_BASIC_PATTERN_STRING = "(([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){1}(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){2}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"; + private static final Pattern IPV4_PATTERN = Pattern.compile("^(([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){1}(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){2}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); + private static final Pattern IPV4_MAPPED_IPV6_PATTERN = Pattern.compile("^::[fF]{4}:(([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){1}(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){2}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); + private static final Pattern IPV6_STD_PATTERN = Pattern.compile("^[0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4}){7}$"); + private static final Pattern IPV6_HEX_COMPRESSED_PATTERN = Pattern.compile("^(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)::(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)$"); + private static final char COLON_CHAR = ':'; + private static final int MAX_COLON_COUNT = 7; + + private IPAddressUtils() { + + } + + public static boolean isIPv4Address(String input) { + return IPV4_PATTERN.matcher(input).matches(); + } + + public static boolean isIPv4MappedIPv64Address(String input) { + return IPV4_MAPPED_IPV6_PATTERN.matcher(input).matches(); + } + + public static boolean isIPv6StdAddress(String input) { + return IPV6_STD_PATTERN.matcher(input).matches(); + } + + public static boolean isIPv6HexCompressedAddress(String input) { + int colonCount = 0; + + for(int i = 0; i < input.length(); ++i) { + if (input.charAt(i) == ':') { + ++colonCount; + } + } + + return colonCount <= 7 && IPV6_HEX_COMPRESSED_PATTERN.matcher(input).matches(); + } + + public static boolean isIPv6Address(String input) { + return isIPv6StdAddress(input) || isIPv6HexCompressedAddress(input); + } + + public static String getLocalIpAddress() { + List list = new ArrayList<>(); + try { + String ipv4; + ArrayList nilist = Collections.list(NetworkInterface.getNetworkInterfaces()); + for (NetworkInterface ni : nilist) { + ArrayList ialist = Collections.list(ni.getInetAddresses()); + for (InetAddress address : ialist) { + if (!address.isLoopbackAddress()) { + ipv4 = address.getHostAddress(); + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { + if (isIPv4Address(ipv4)) { + list.add(ipv4); +// return ipv4; + } + } else { + if (address instanceof Inet4Address) { + list.add(ipv4); +// return ipv4; + } + } + } + } + } + if (!list.isEmpty()){ + if (list.size() ==1) + return list.get(0); + for (String ip :list) { + if (ip.startsWith("127.0."))continue; + if (ip.startsWith("192.168."))continue; + return ip; + } + } + return ipAddress(); + } catch (SocketException ex) { + Log.e("localip", ex.toString()); + return ipAddress(); + } + } + + public static String ipAddress() { + try { + for (final Enumeration enumerationNetworkInterface = NetworkInterface.getNetworkInterfaces(); enumerationNetworkInterface.hasMoreElements(); ) { + final NetworkInterface networkInterface = enumerationNetworkInterface.nextElement(); + for (Enumeration enumerationInetAddress = networkInterface.getInetAddresses(); enumerationInetAddress.hasMoreElements(); ) { + final InetAddress inetAddress = enumerationInetAddress.nextElement(); + final String ipAddress = inetAddress.getHostAddress(); + if (!inetAddress.isLoopbackAddress()){ + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { + if (isIPv4Address(ipAddress)) { + return ipAddress; + } + } else { + if (inetAddress instanceof Inet4Address) { + return ipAddress; + } + } + } + } + } + return "127.0.0.1"; + } catch (final Exception e) { + LogUtils.e("获取Ip失败:" + e.getMessage()); + return "127.0.0.1"; + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/IdcardUtils.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/IdcardUtils.java new file mode 100644 index 0000000..be5a612 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/IdcardUtils.java @@ -0,0 +1,676 @@ +package com.ycgis.macall.personalcenter.util; + +import android.annotation.SuppressLint; + +import com.rs.macall.androidx.basemodel.utils.StringUtil; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by Administrator on 2018/1/2. + */ + +public class IdcardUtils { + /** + * 中国公民身份证号码最小长度。 + */ + public static final int CHINA_ID_MIN_LENGTH = 15; + /** + * 中国公民身份证号码最大长度。 + */ + public static final int CHINA_ID_MAX_LENGTH = 18; + /** + * 省、直辖市代码表 + */ + public static final String cityCode[] = { + "11", "12", "13", "14", "15", "21", "22", "23", "31", "32", "33", "34", "35", "36", "37", "41", + "42", "43", "44", "45", "46", "50", "51", "52", "53", "54", "61", "62", "63", "64", "65", "71", + "81", "82", "91" + }; + /** + * 每位加权因子 + */ + public static final int power[] = { + 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 + }; + /** + * 第18位校检码 + */ + public static final String verifyCode[] = { + "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" + }; + /** + * 最低年限 + */ + public static final int MIN = 1930; + public static Map cityCodes = new HashMap(); + /** + * 台湾身份首字母对应数字 + */ + public static Map twFirstCode = new HashMap(); + /** + * 香港身份首字母对应数字 + */ + public static Map hkFirstCode = new HashMap(); + + static { + cityCodes.put("11", "北京"); + cityCodes.put("12", "天津"); + cityCodes.put("13", "河北"); + cityCodes.put("14", "山西"); + cityCodes.put("15", "内蒙古"); + cityCodes.put("21", "辽宁"); + cityCodes.put("22", "吉林"); + cityCodes.put("23", "黑龙江"); + cityCodes.put("31", "上海"); + cityCodes.put("32", "江苏"); + cityCodes.put("33", "浙江"); + cityCodes.put("34", "安徽"); + cityCodes.put("35", "福建"); + cityCodes.put("36", "江西"); + cityCodes.put("37", "山东"); + cityCodes.put("41", "河南"); + cityCodes.put("42", "湖北"); + cityCodes.put("43", "湖南"); + cityCodes.put("44", "广东"); + cityCodes.put("45", "广西"); + cityCodes.put("46", "海南"); + cityCodes.put("50", "重庆"); + cityCodes.put("51", "四川"); + cityCodes.put("52", "贵州"); + cityCodes.put("53", "云南"); + cityCodes.put("54", "西藏"); + cityCodes.put("61", "陕西"); + cityCodes.put("62", "甘肃"); + cityCodes.put("63", "青海"); + cityCodes.put("64", "宁夏"); + cityCodes.put("65", "新疆"); + cityCodes.put("71", "台湾"); + cityCodes.put("81", "香港"); + cityCodes.put("82", "澳门"); + cityCodes.put("91", "国外"); + twFirstCode.put("A", 10); + twFirstCode.put("B", 11); + twFirstCode.put("C", 12); + twFirstCode.put("D", 13); + twFirstCode.put("E", 14); + twFirstCode.put("F", 15); + twFirstCode.put("G", 16); + twFirstCode.put("H", 17); + twFirstCode.put("J", 18); + twFirstCode.put("K", 19); + twFirstCode.put("L", 20); + twFirstCode.put("M", 21); + twFirstCode.put("N", 22); + twFirstCode.put("P", 23); + twFirstCode.put("Q", 24); + twFirstCode.put("R", 25); + twFirstCode.put("S", 26); + twFirstCode.put("T", 27); + twFirstCode.put("U", 28); + twFirstCode.put("V", 29); + twFirstCode.put("X", 30); + twFirstCode.put("Y", 31); + twFirstCode.put("W", 32); + twFirstCode.put("Z", 33); + twFirstCode.put("I", 34); + twFirstCode.put("O", 35); + hkFirstCode.put("A", 1); + hkFirstCode.put("B", 2); + hkFirstCode.put("C", 3); + hkFirstCode.put("R", 18); + hkFirstCode.put("U", 21); + hkFirstCode.put("Z", 26); + hkFirstCode.put("X", 24); + hkFirstCode.put("W", 23); + hkFirstCode.put("O", 15); + hkFirstCode.put("N", 14); + } + + /** + * 将15位身份证号码转换为18位 + * + * @param idCard 15位身份编码 + * @return 18位身份编码 + */ + public static String conver15CardTo18(String idCard) { + String idCard18 = ""; + if (idCard.length() != CHINA_ID_MIN_LENGTH) { + return idCard; + } + if (isNum(idCard)) { + // 获取出生年月日 + String birthday = idCard.substring(6, 12); + Date birthDate = null; + try { + birthDate = new SimpleDateFormat("yyMMdd").parse(birthday); + } catch (ParseException e) { + e.printStackTrace(); + } + Calendar cal = Calendar.getInstance(); + if (birthDate != null) + cal.setTime(birthDate); + // 获取出生年(完全表现形式,如:2010) + String sYear = String.valueOf(cal.get(Calendar.YEAR)); + idCard18 = idCard.substring(0, 6) + sYear + idCard.substring(8); + // 转换字符数组 + char[] cArr = idCard18.toCharArray(); + if (cArr != null) { + int[] iCard = converCharToInt(cArr); + int iSum17 = getPowerSum(iCard); + // 获取校验位 + String sVal = getCheckCode18(iSum17); + if (sVal.length() > 0) { + idCard18 += sVal; + } else { + return idCard; + } + } + } else { + return idCard; + } + return idCard18; + } + + /** + * 验证身份证是否合法 + */ + public static boolean validateCard15(String idCard) { + String card = idCard.trim(); + if (validateIdCard18(card)) { + return true; + } + //15位的不可查 + if (validateIdCard15(card)) { + return true; + } + return true; + } + + + /** + * 验证身份证是否合法 + */ + public static boolean validateCard(String idCard) { + String card = idCard.trim(); + if (validateIdCard18(card)) { + return true; + } +// //15位的不可查 +// if (validateIdCard15(card)) { +// return false; +// } + if (card.length() == 8) { + return false; + } + String[] cardval = validateIdCard10(card); + if (cardval != null) { + if (cardval[2].equals("true")) { + return true; + } + } + return false; + } + + /** + * 验证18位身份编码是否合法 + * + * @param idCard 身份编码 + * @return 是否合法 + */ + public static boolean validateIdCard18(String idCard) { + boolean bTrue = false; + if (idCard.length() == CHINA_ID_MAX_LENGTH) { + // 前17位 + String code17 = idCard.substring(0, 17); + // 第18位 + String code18 = idCard.substring(17, CHINA_ID_MAX_LENGTH); + if (isNum(code17)) { + char[] cArr = code17.toCharArray(); + if (cArr != null) { + int[] iCard = converCharToInt(cArr); + int iSum17 = getPowerSum(iCard); + // 获取校验位 + String val = getCheckCode18(iSum17); + if (val.length() > 0) { + if (val.equalsIgnoreCase(code18)) { + bTrue = true; + } + } + } + } + } + return bTrue; + } + + /** + * 验证15位身份编码是否合法 + * + * @param idCard 身份编码 + * @return 是否合法 + */ + @SuppressLint("SimpleDateFormat") + public static boolean validateIdCard15(String idCard) { + if (idCard.length() != CHINA_ID_MIN_LENGTH) { + return false; + } + if (isNum(idCard)) { + String proCode = idCard.substring(0, 2); + if (cityCodes.get(proCode) == null) { + return false; + } + String birthCode = idCard.substring(6, 12); + Date birthDate = null; + try { + birthDate = new SimpleDateFormat("yy").parse(birthCode.substring(0, 2)); + } catch (ParseException e) { + e.printStackTrace(); + } + Calendar cal = Calendar.getInstance(); + if (birthDate != null) + cal.setTime(birthDate); + try { + if (!valiDate(cal.get(Calendar.YEAR), Integer.parseInt(birthCode.substring(2, 4)), + Integer.parseInt(birthCode.substring(4, 6)))) { + return false; + } + }catch (NumberFormatException e){ + e.printStackTrace(); + return false; + } + } else { + return false; + } + return true; + } + + /** + * 验证10位身份编码是否合法 + * + * @param idCard 身份编码 + * @return 身份证信息数组 + *

+ * [0] - 台湾、澳门、香港 [1] - 性别(男M,女F,未知N) [2] - 是否合法(合法true,不合法false) + * 若不是身份证件号码则返回null + *

+ */ + public static String[] validateIdCard10(String idCard) { + String[] info = new String[3]; + String card = idCard.replaceAll("[\\(|\\)]", ""); + if (card.length() != 8 && card.length() != 9 && idCard.length() != 10) { + return null; + } + if (idCard.matches("^[a-zA-Z][0-9]{9}$")) { // 台湾 + info[0] = "台湾"; + System.out.println("11111"); + String char2 = idCard.substring(1, 2); + if (char2.equals("1")) { + info[1] = "M"; + System.out.println("MMMMMMM"); + } else if (char2.equals("2")) { + info[1] = "F"; + System.out.println("FFFFFFF"); + } else { + info[1] = "N"; + info[2] = "false"; + System.out.println("NNNN"); + return info; + } + info[2] = validateTWCard(idCard) ? "true" : "false"; + } else if (idCard.matches("^[1|5|7][0-9]{6}\\(?[0-9A-Z]\\)?$")) { // 澳门 + info[0] = "澳门"; + info[1] = "N"; + // TODO + } else if (idCard.matches("^[A-Z]{1,2}[0-9]{6}\\(?[0-9A]\\)?$")) { // 香港 + info[0] = "香港"; + info[1] = "N"; + info[2] = validateHKCard(idCard) ? "true" : "false"; + } else { + return null; + } + return info; + } + + /** + * 验证台湾身份证号码 + * + * @param idCard 身份证号码 + * @return 验证码是否符合 + */ + public static boolean validateTWCard(String idCard) { + String start = idCard.substring(0, 1); + String mid = idCard.substring(1, 9); + String end = idCard.substring(9, 10); + Integer iStart = twFirstCode.get(start); + Integer sum = iStart / 10 + (iStart % 10) * 9; + char[] chars = mid.toCharArray(); + Integer iflag = 8; + for (char c : chars) { + sum = sum + Integer.valueOf(c + "") * iflag; + iflag--; + } + return (sum % 10 == 0 ? 0 : (10 - sum % 10)) == Integer.valueOf(end) ? true : false; + } + + /** + * 验证香港身份证号码(存在Bug,部份特殊身份证无法检查) + *

+ * 身份证前2位为英文字符,如果只出现一个英文字符则表示第一位是空格,对应数字58 前2位英文字符A-Z分别对应数字10-35 + * 最后一位校验码为0-9的数字加上字符"A","A"代表10 + *

+ *

+ * 将身份证号码全部转换为数字,分别对应乘9-1相加的总和,整除11则证件号码有效 + *

+ * + * @param idCard 身份证号码 + * @return 验证码是否符合 + */ + public static boolean validateHKCard(String idCard) { + String card = idCard.replaceAll("[\\(|\\)]", ""); + Integer sum = 0; + if (card.length() == 9) { + sum = (Integer.valueOf(card.substring(0, 1).toUpperCase().toCharArray()[0]) - 55) * 9 + + (Integer.valueOf(card.substring(1, 2).toUpperCase().toCharArray()[0]) - 55) * 8; + card = card.substring(1, 9); + } else { + sum = 522 + (Integer.valueOf(card.substring(0, 1).toUpperCase().toCharArray()[0]) - 55) * 8; + } + String mid = card.substring(1, 7); + String end = card.substring(7, 8); + char[] chars = mid.toCharArray(); + Integer iflag = 7; + for (char c : chars) { + sum = sum + Integer.valueOf(c + "") * iflag; + iflag--; + } + if (end.toUpperCase().equals("A")) { + sum = sum + 10; + } else { + sum = sum + Integer.valueOf(end); + } + return (sum % 11 == 0) ? true : false; + } + + /** + * 将字符数组转换成数字数组 + * + * @param ca 字符数组 + * @return 数字数组 + */ + public static int[] converCharToInt(char[] ca) { + int len = ca.length; + int[] iArr = new int[len]; + try { + for (int i = 0; i < len; i++) { + iArr[i] = Integer.parseInt(String.valueOf(ca[i])); + } + } catch (NumberFormatException e) { + e.printStackTrace(); + } + return iArr; + } + + /** + * 将身份证的每位和对应位的加权因子相乘之后,再得到和值 + * + * @param iArr + * @return 身份证编码。 + */ + public static int getPowerSum(int[] iArr) { + int iSum = 0; + if (power.length == iArr.length) { + for (int i = 0; i < iArr.length; i++) { + for (int j = 0; j < power.length; j++) { + if (i == j) { + iSum = iSum + iArr[i] * power[j]; + } + } + } + } + return iSum; + } + + /** + * 将power和值与11取模获得余数进行校验码判断 + * + * @param iSum + * @return 校验位 + */ + public static String getCheckCode18(int iSum) { + String sCode = ""; + switch (iSum % 11) { + case 10: + sCode = "2"; + break; + case 9: + sCode = "3"; + break; + case 8: + sCode = "4"; + break; + case 7: + sCode = "5"; + break; + case 6: + sCode = "6"; + break; + case 5: + sCode = "7"; + break; + case 4: + sCode = "8"; + break; + case 3: + sCode = "9"; + break; + case 2: + sCode = "X"; + break; + case 1: + sCode = "0"; + break; + case 0: + sCode = "1"; + break; + } + return sCode; + } + + /** + * 根据身份编号获取年龄 + * + * @param idCard 身份编号 + * @return 年龄 + */ + public static int getAgeByIdCard(String idCard) { + int iAge = 0; + if (idCard.length() == CHINA_ID_MIN_LENGTH) { + idCard = conver15CardTo18(idCard); + } + String year = idCard.substring(6, 10); + Calendar cal = Calendar.getInstance(); + int iCurrYear = cal.get(Calendar.YEAR); + iAge = iCurrYear - Integer.valueOf(year); + return iAge; + } + + /** + * 根据身份编号获取生日 + * + * @param idCard 身份编号 + * @return 生日(yyyyMMdd) + */ + public static String getBirthByIdCard(String idCard) { + Integer len = idCard.length(); + if (len < CHINA_ID_MIN_LENGTH) { + return null; + } else if (len == CHINA_ID_MIN_LENGTH) { + idCard = conver15CardTo18(idCard); + } + return idCard.substring(6, 14); + } + + /** + * 根据身份编号获取生日年 + * + * @param idCard 身份编号 + * @return 生日(yyyy) + */ + public static Short getYearByIdCard(String idCard) { + Integer len = idCard.length(); + if (len < CHINA_ID_MIN_LENGTH) { + return null; + } else if (len == CHINA_ID_MIN_LENGTH) { + idCard = conver15CardTo18(idCard); + } + return Short.valueOf(idCard.substring(6, 10)); + } + + /** + * 根据身份编号获取生日月 + * + * @param idCard 身份编号 + * @return 生日(MM) + */ + public static Short getMonthByIdCard(String idCard) { + Integer len = idCard.length(); + if (len < CHINA_ID_MIN_LENGTH) { + return null; + } else if (len == CHINA_ID_MIN_LENGTH) { + idCard = conver15CardTo18(idCard); + } + return Short.valueOf(idCard.substring(10, 12)); + } + + /** + * 根据身份编号获取生日天 + * + * @param idCard 身份编号 + * @return 生日(dd) + */ + public static Short getDateByIdCard(String idCard) { + Integer len = idCard.length(); + if (len < CHINA_ID_MIN_LENGTH) { + return null; + } else if (len == CHINA_ID_MIN_LENGTH) { + idCard = conver15CardTo18(idCard); + } + return Short.valueOf(idCard.substring(12, 14)); + } + + /** + * 根据身份编号获取性别 + * + * @param idCard 身份编号 + * @return 性别(M - icon_man , F - icon_woman , N - 未知) + */ + public static String getGenderByIdCard(String idCard) { + String sGender = "N"; + if (StringUtil.isNullOrEmpty(idCard)||idCard.length()<15){ + return sGender; + } + if (idCard.length() == CHINA_ID_MIN_LENGTH) { + idCard = conver15CardTo18(idCard); + } + String sCardNum = idCard.substring(16, 17); + if (Integer.parseInt(sCardNum) % 2 != 0) { + sGender = "M"; + } else { + sGender = "F"; + } + return sGender; + } + + /** + * 根据身份编号获取户籍省份 + * + * @param idCard 身份编码 + * @return 省级编码。 + */ + public static String getProvinceByIdCard(String idCard) { + int len = idCard.length(); + String sProvince = null; + String sProvinNum = ""; + if (len == CHINA_ID_MIN_LENGTH || len == CHINA_ID_MAX_LENGTH) { + sProvinNum = idCard.substring(0, 2); + } + sProvince = cityCodes.get(sProvinNum); + return sProvince; + } + + /** + * 判断是否是身份证开头 + * + * @param idCard 要判断的身份证号 + * @return null 或者省份 + */ + public static String isStartIdCard(String idCard) { + if (idCard == null) return null; + if (idCard.length() < 2) return null; + String sProvinNum = idCard.substring(0, 2); + return cityCodes.get(sProvinNum); + } + + /** + * 数字验证 + * + * @param val 需要验证的字符串 + */ + public static boolean isNum(String val) { + return val != null && !"".equals(val) && val.matches("^[0-9]*$"); + } + + /** + * 验证小于当前日期 是否有效 + * + * @param iYear 待验证日期(年) + * @param iMonth 待验证日期(月 1-12) + * @param iDate 待验证日期(日) + * @return 是否有效 + */ + public static boolean valiDate(int iYear, int iMonth, int iDate) { + Calendar cal = Calendar.getInstance(); + int year = cal.get(Calendar.YEAR); + int datePerMonth; + if (iYear < MIN || iYear >= year) { + return false; + } + if (iMonth < 1 || iMonth > 12) { + return false; + } + switch (iMonth) { + case 4: + case 6: + case 9: + case 11: + datePerMonth = 30; + break; + case 2: + boolean dm = ((iYear % 4 == 0 && iYear % 100 != 0) || (iYear % 400 == 0)) + && (iYear > MIN && iYear < year); + datePerMonth = dm ? 29 : 28; + break; + default: + datePerMonth = 31; + } + return (iDate >= 1) && (iDate <= datePerMonth); + } + + public static boolean isCarnumberNO(String carnumber) { + if (StringUtil.isNullOrEmpty(carnumber)) return false; + String carnumRegex = "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF])|([DF]([A-HJ-NP-Z0-9])[0-9]{4})))|([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1})"; + return carnumber.matches(carnumRegex); + } + + public static boolean isWan(String cph) { + if (StringUtil.isNullOrEmpty(cph)) return false; + String ss = "^[A-Z]"; + return cph.matches(ss); + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/ImageOptimizationUtil.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/ImageOptimizationUtil.java new file mode 100644 index 0000000..f780352 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/ImageOptimizationUtil.java @@ -0,0 +1,197 @@ +package com.ycgis.macall.personalcenter.util; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.ColorSpace; + +import com.rs.macall.androidx.basemodel.utils.BitMapUtils; + +import java.io.File; +import java.io.IOException; + +/** + * created by: Macall + * create time: 2024/1/11 9:09 + * copyright: @ruansee.com + * Describe: + */ +public class ImageOptimizationUtil { + // 阈值0-255 + public static int YZ = 200; + + /** + * 图像二值化处理 + * + * @param filePath 要处理的图片路径 + * @param fileOutputPath 处理后的图片输出路径 + */ + public static void binarization(String filePath, String fileOutputPath) throws IOException { +// File file = new File(filePath); + Bitmap bitmap = BitmapFactory.decodeFile(filePath); +// BufferedImage bi = ImageIO.read(file); + // 获取当前图片的高,宽,ARGB + int h = bitmap.getHeight(); + int w = bitmap.getWidth(); + int arr[][] = new int[w][h]; + + // 获取图片每一像素点的灰度值 + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + // getRGB()返回默认的RGB颜色模型(十进制) + arr[i][j] = getImageGray(bitmap.getPixel(i, j));// 该点的灰度值 + } + } + Bitmap bitmaps = Bitmap.createBitmap(w, h, + Bitmap.Config.ARGB_8888); + // 构造一个类型为预定义图像类型,BufferedImage +// BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY); + + // 和预先设置的阈值大小进行比较,大的就显示为255即白色,小的就显示为0即黑色 + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + if (getGray(arr, i, j, w, h) > YZ) { + int rgb = Color.rgb(255, 255, 255); +// int rgb = new Color(255, 255, 255).getRGB(); + bitmaps.setPixel(i, j, rgb); + } else { + int black = Color.rgb(0, 0, 0); +// int black = new Color(0, 0, 0).getRGB(); + bitmaps.setPixel(i, j, black); + } + } + } + BitMapUtils.saveBitmapFile(bitmap,new File(fileOutputPath)); + } + + /** + * 图像的灰度处理 + * 利用浮点算法:Gray = R*0.3 + G*0.59 + B*0.11; + * + * @param rgb 该点的RGB值 + * @return 返回处理后的灰度值 + */ + private static int getImageGray(int rgb) { + String argb = Integer.toHexString(rgb);// 将十进制的颜色值转为十六进制 + // argb分别代表透明,红,绿,蓝 分别占16进制2位 + int r = Integer.parseInt(argb.substring(2, 4), 16);// 后面参数为使用进制 + int g = Integer.parseInt(argb.substring(4, 6), 16); + int b = Integer.parseInt(argb.substring(6, 8), 16); + int gray = (int) (r*0.28 + g*0.95 + b*0.11); + return gray; + } + + /** + * 自己加周围8个灰度值再除以9,算出其相对灰度值 + * + * @param gray + * @param x 要计算灰度的点的横坐标 + * @param y 要计算灰度的点的纵坐标 + * @param w 图像的宽度 + * @param h 图像的高度 + * @return + */ + public static int getGray(int gray[][], int x, int y, int w, int h) { + int rs = gray[x][y] + (x == 0 ? 255 : gray[x - 1][y]) + (x == 0 || y == 0 ? 255 : gray[x - 1][y - 1]) + + (x == 0 || y == h - 1 ? 255 : gray[x - 1][y + 1]) + (y == 0 ? 255 : gray[x][y - 1]) + + (y == h - 1 ? 255 : gray[x][y + 1]) + (x == w - 1 ? 255 : gray[x + 1][y]) + + (x == w - 1 || y == 0 ? 255 : gray[x + 1][y - 1]) + + (x == w - 1 || y == h - 1 ? 255 : gray[x + 1][y + 1]); + return rs / 9; + } + +// /** +// * 二值化后的图像的开运算:先腐蚀再膨胀(用于去除图像的小黑点) +// * +// * @param filePath 要处理的图片路径 +// * @param fileOutputPath 处理后的图片输出路径 +// * @throws IOException +// */ +// public static void opening(String filePath, String fileOutputPath) throws IOException { +// File file = new File(filePath); +// BufferedImage bi = ImageIO.read(file); +// // 获取当前图片的高,宽,ARGB +// int h = bi.getHeight(); +// int w = bi.getWidth(); +// int arr[][] = new int[w][h]; +// // 获取图片每一像素点的灰度值 +// for (int i = 0; i < w; i++) { +// for (int j = 0; j < h; j++) { +// // getRGB()返回默认的RGB颜色模型(十进制) +// arr[i][j] = getImageGray(bi.getRGB(i, j));// 该点的灰度值 +// } +// } +// +// int black = new Color(0, 0, 0).getRGB(); +// int white = new Color(255, 255, 255).getRGB(); +// BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY); +// // 临时存储腐蚀后的各个点的亮度 +// int temp[][] = new int[w][h]; +// // 1.先进行腐蚀操作 +// for (int i = 0; i < w; i++) { +// for (int j = 0; j < h; j++) { +// /* +// * 为0表示改点和周围8个点都是黑,则该点腐蚀操作后为黑 +// * 由于公司图片态模糊,完全达到9个点全为黑的点太少,最后效果很差,故改为了小于30 +// * (写30的原因是,当只有一个点为白,即总共255,调用getGray方法后得到255/9 = 28) +// */ +// if (getGray(arr, i, j, w, h) < 30) { +// temp[i][j] = 0; +// } else{ +// temp[i][j] = 255; +// } +// } +// } +// +// // 2.再进行膨胀操作 +// for (int i = 0; i < w; i++) { +// for (int j = 0; j < h; j++) { +// bufferedImage.setRGB(i, j, white); +// } +// } +// for (int i = 0; i < w; i++) { +// for (int j = 0; j < h; j++) { +// // 为0表示改点和周围8个点都是黑,则该点腐蚀操作后为黑 +// if (temp[i][j] == 0) { +// bufferedImage.setRGB(i, j, black); +// if(i > 0) { +// bufferedImage.setRGB(i-1, j, black); +// } +// if (j > 0) { +// bufferedImage.setRGB(i, j-1, black); +// } +// if (i > 0 && j > 0) { +// bufferedImage.setRGB(i-1, j-1, black); +// } +// if (j < h-1) { +// bufferedImage.setRGB(i, j+1, black); +// } +// if (i < w-1) { +// bufferedImage.setRGB(i+1, j, black); +// } +// if (i < w-1 && j > 0) { +// bufferedImage.setRGB(i+1, j-1, black); +// } +// if (i < w-1 && j < h-1) { +// bufferedImage.setRGB(i+1, j+1, black); +// } +// if (i > 0 && j < h-1) { +// bufferedImage.setRGB(i-1, j+1, black); +// } +// } +// } +// } +// +// ImageIO.write(bufferedImage, "jpeg", new File(fileOutputPath)); +// } + + public static void main(String[] args) { + String fullPath="code.jpeg"; + String newPath="code2.jpeg"; + try { + ImageOptimizationUtil.binarization(fullPath,newPath); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/InsertAppUtils.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/InsertAppUtils.java new file mode 100644 index 0000000..7954c1b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/InsertAppUtils.java @@ -0,0 +1,103 @@ +package com.ycgis.macall.personalcenter.util; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Build; +import android.provider.Settings; + +import java.io.File; + +/** + * created by: Macall + * create time: 2023/2/2 15:33 + * copyright: @ruansee.com + * Describe: 安装应用 + */ +public class InsertAppUtils { + + /** + * 检测是否安装应用 + * @param context 上下文环境 + * @return true 未安装 false 安装 + */ + public boolean isInspectStaticFaceSDK(Context context) { + PackageInfo packageInfo = null; + try { + packageInfo = context.getPackageManager().getPackageInfo("com.ruansee.unifiedservicecomponent", 0); + } catch (PackageManager.NameNotFoundException e) { + packageInfo = null; + e.printStackTrace(); + } + return packageInfo == null; + } + + /** + * 检测本地安装的版本是否需要更是 + * @param context 上下文环境 + * @return true 不需要更新 false 需要安装 + */ + public boolean isUpdateStaticFaceSDK(Context context) { + PackageInfo packageInfo = null; + try { + //读取本地组件版本号,版本号 + packageInfo = context.getPackageManager().getPackageInfo("com.ruansee.unifiedservicecomponent", 0); + if (packageInfo == null) return false; + //这是新版本的 版本号 + int nweCode = 2; + // 满足条件说明 本地安装的是最新版 返回true + return packageInfo.versionCode>=nweCode; + } catch (PackageManager.NameNotFoundException e) { + packageInfo = null; + e.printStackTrace(); + return true; + } + } + + //申请应用安装权限后安装应用 + public void installApp(String titleMessage, Activity context, File file, DialogInterface.OnClickListener cancelClickListener) throws Exception { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + boolean isGranted = context.getPackageManager().canRequestPackageInstalls(); + if (!isGranted) { + applyInstallPermission(context,titleMessage, cancelClickListener); + } else { + instead(context, file); + } + } else { + instead(context, file); + } + } + + //申请应用安装权限 + public void applyInstallPermission(Activity context, String titleMessage,DialogInterface.OnClickListener cancelClickListener) { + new AlertDialog.Builder(context) + .setTitle("重要提示") + .setMessage(titleMessage) + .setCancelable(false) + .setNegativeButton("取消", cancelClickListener) + .setPositiveButton("继续", (dialog, which) -> { + dialog.dismiss(); + Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES); + context.startActivityForResult(intent, 1023); + }).create().show(); + } + + + private void instead(Activity context, File file) throws Exception { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Uri apkUri = UriUtils.getUri(context, file); + intent.setDataAndType(apkUri, "application/vnd.android.package-archive"); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + context.startActivityForResult(intent, 10145); + } else { + context.startActivityForResult(intent, 10145); + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/JiaMi.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/JiaMi.java new file mode 100644 index 0000000..4809981 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/JiaMi.java @@ -0,0 +1,111 @@ +package com.ycgis.macall.personalcenter.util; + +import com.base.code.binary.Base64; + +import java.security.SecureRandom; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESKeySpec; + +/** + * created by: Macall + * create time: 2022/11/1 9:42 + * copyright: @ruansee.com + * Describe: + */ +public class JiaMi { + + /** + * 根据 key 加密 data , 并将加密后的数据进行Base64转码 + * @param data 待加密的数据 + * @param id id + * @param secret 秘钥 + * @return Base64字符 + */ + public static String desCrypto(byte[] data, String id,String secret) { + return desCrypto(data,String.format("%s:%s",id,secret)); + } + + /** + * 根据 key 加密 data , 并将加密后的数据进行Base64转码 + * @param data 待加密的数据 + * @param key 加密的KEY + * @return Base64字符 + */ + public static String desCrypto(byte[] data, String key) { + try{ + SecureRandom random = new SecureRandom(); + DESKeySpec desKey = new DESKeySpec(key.getBytes()); + //创建一个密匙工厂,然后用它把DESKeySpec转换成 + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + SecretKey securekey = keyFactory.generateSecret(desKey); + //Cipher对象实际完成加密操作 + Cipher cipher = Cipher.getInstance("DES"); + //用密匙初始化Cipher对象 + cipher.init(Cipher.ENCRYPT_MODE, securekey, random); + //现在,获取数据并加密 + //正式执行加密操作 + byte[] bytes = cipher.doFinal(data); + //进行Base64转码 + return Base64.encodeBase64String(bytes); + }catch(Throwable e){ + e.printStackTrace(); + } + return null; + } + + /** + * DES 解密 + * @param data 加密后的字符 + * @param key key + * @return 解密后的数据 + * @throws Exception 异常信息 + */ + public static byte[] decrypt(byte[] data, String key) throws Exception { + // DES算法要求有一个可信任的随机数源 + SecureRandom random = new SecureRandom(); + // 创建一个DESKeySpec对象 + DESKeySpec desKey = new DESKeySpec(key.getBytes()); + // 创建一个密匙工厂 + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + // 将DESKeySpec对象转换成SecretKey对象 + SecretKey securekey = keyFactory.generateSecret(desKey); + // Cipher对象实际完成解密操作 + Cipher cipher = Cipher.getInstance("DES"); + // 用密匙初始化Cipher对象 + cipher.init(Cipher.DECRYPT_MODE, securekey, random); + // 真正开始解密操作 + return cipher.doFinal(data); + } + + /** + * DES 解密 + * @param encryptData 加密后的字符 + * @param key key + * @return 解密后的数据 + * @throws Exception 异常信息 + */ + public static String decrypt(String encryptData, String key) throws Exception { + byte[] data = Base64.decodeBase64(encryptData); + byte[] decrypt = decrypt(data, key); + return new String(decrypt,"UTF-8"); + } + + /** + * DES 解密 + * @param encryptData 加密后的字符 + * @param id ID + * @param secret 秘钥 + * @return 解密后的数据 + * @throws Exception 异常信息 + */ + public static String decrypt(String encryptData, String id,String secret) throws Exception { + byte[] data = Base64.decodeBase64(encryptData); + byte[] decrypt = decrypt(data, String.format("%s:%s",id,secret)); + return new String(decrypt,"UTF-8"); + } + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/LocationGPSManage.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/LocationGPSManage.java new file mode 100644 index 0000000..4dfe602 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/LocationGPSManage.java @@ -0,0 +1,381 @@ +package com.ycgis.macall.personalcenter.util; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Criteria; +import android.location.GnssStatus; +import android.location.GpsSatellite; +import android.location.GpsStatus; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.location.LocationProvider; +import android.os.Build; +import android.os.Bundle; + +import androidx.annotation.RequiresApi; +import androidx.core.app.ActivityCompat; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleObserver; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.OnLifecycleEvent; + +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.GPSLocationListener; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * created by: Macall + * create time: 2023/3/28 9:30 + * copyright: @ruansee.com + * Describe: 封装了GPS定位工具类 该类实现了 LifecycleObserver 用于监听 Activity 和 Fragment 的生命周期 + * 避免因退出页面而忘记关闭定位导致应用耗时增加的问题 + * TODO @see #onDestroy(LifecycleOwner) 使用时请在调用者(Activity 或 Fragment ) 调用如下代码 + * TODO { getLifecycle().addObserver(locationGPSManage) } + */ +public class LocationGPSManage implements LifecycleObserver { + private static LocationGPSManage locationGPSManage; + private LocationManager locationManager; + private boolean isLocation = false; + private MyLocationListener locationListener; + private MyGPSListener gpsListener; + private GnssStatus.Callback gnssStatusCallback; + + /** + * 记录上次搜索到的卫星数 + */ + private int startCount = -1; + + private List locationListenerList; + + /** + * 该方法不需要手动调用 + * 宿主执行了onDestroy时 会分发该事件 + * 使用时请在宿主(Activity 或 Fragment ) 中调用如下代码,调用后当 宿主执行什么周期方法 onDestroy 该方法自动被调用 + * { getLifecycle().addObserver(locationGPSManage) } + */ + @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) + void onDestroy(@NotNull LifecycleOwner owner) { + stopLocation(); + } + + private LocationGPSManage() { + } + + /** + * 添加一个位置监听 + * + * @param gpsLocationListener 监听接口实例对象 + */ + @NotNull + public void addGPSLocationListener(@NotNull GPSLocationListener gpsLocationListener) { + if (locationListenerList == null) { + locationListenerList = new ArrayList<>(); + } + if (locationListenerList.contains(gpsLocationListener)) return; + locationListenerList.add(gpsLocationListener); + } + + public static synchronized LocationGPSManage getInstance() { + if (locationGPSManage == null) { + synchronized (LocationGPSManage.class) { + if (locationGPSManage == null) { + locationGPSManage = new LocationGPSManage(); + } + } + } + return locationGPSManage; + } + + /** + * 开启定位 + * + * @param context 上下文环境 + * @param gpsLocationListener 位置监听,也可以调用{@link #addGPSLocationListener(GPSLocationListener)}方法传递 + * @throws RuntimeException 要先获取定位权限,否则将抛出异常 + */ + @SuppressLint("MissingPermission") + public void startGPSLocation(Context context, GPSLocationListener gpsLocationListener) throws RuntimeException { + boolean gpsPermission = isGPSPermission(context); + if (!gpsPermission) + throw new RuntimeException("Not ACCESS_FINE_LOCATION AND ACCESS_COARSE_LOCATION Permission"); + //避免重复开启定位,该实例只允许开启一次定位 + if (isLocation) return; + if (gpsLocationListener != null) { + addGPSLocationListener(gpsLocationListener); + } + LogUtils.w("启动GPS定位"); + locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + + String bestProvider = locationManager.getBestProvider(getCriteria(), true); + String currentProvider = "gps"; + if ("gps".equals(bestProvider)) { + currentProvider = bestProvider; + } else { + //根据设置的Criteria对象,获取最符合此标准的provider对象 + LocationProvider provider = locationManager.getProvider(LocationManager.GPS_PROVIDER); + if (provider != null) { + currentProvider = provider.getName(); + } + } + LogUtils.w("获取的定位类型:" + currentProvider); + //根据当前provider对象获取最后一次位置信息 + Location currentLocation = locationManager.getLastKnownLocation(currentProvider); + if (locationListener == null) { + locationListener = new MyLocationListener(); + } + //如果位置信息不为NULL,则通知调用者最后一次位置 + if (currentLocation != null) { + locationListener.onLocationChanged(currentLocation); + } + //根据系统版本确定使用哪个卫星搜索监听 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (gnssStatusCallback == null) { + gnssStatusCallback = getGnssStatusCallback(); + } + locationManager.registerGnssStatusCallback(gnssStatusCallback); + } else { + if (gpsListener == null) { + gpsListener = new MyGPSListener(); + } + locationManager.addGpsStatusListener(gpsListener); + } + locationManager.requestLocationUpdates(currentProvider, 5 * 1000, 3, locationListener); + isLocation = true; + } + + /** + * 开启定位 + * + * @param context 上下文环境 + * @throws RuntimeException 要先获取定位权限,否则将抛出异常 + */ + @SuppressLint("MissingPermission") + public void startGPSLocation(Context context) throws RuntimeException { + startGPSLocation(context, null); + } + + private Criteria getCriteria() { + Criteria criteria = new Criteria(); +// 设置定位精确度 Criteria.ACCURACY_COARSE比较粗略,Criteria.ACCURACY_FINE则比较精细 + criteria.setAccuracy(Criteria.ACCURACY_COARSE); +// 设置是否要求速度 + criteria.setSpeedRequired(false); +// 设置是否允许运营商收费 + criteria.setCostAllowed(false); +// 设置是否需要方位信息 + criteria.setBearingRequired(true); +// 设置是否需要海拔信息 + criteria.setAltitudeRequired(true); +// 设置对电源的需求 + criteria.setPowerRequirement(Criteria.POWER_LOW); + return criteria; + } + + /** + * 停止定位,无论 {@link #startGPSLocation(Context)} 被执行多少此,该方法被执行时将停止位置监听,其他以监听位置的活动也无法继续获取位置监听 + * 需要重新执行 startGPSLocation 才能继续监听位置 + * TODO 该方法被调用后 所有的 调用 {@link #addGPSLocationListener(GPSLocationListener)}该方法添加的监听都会被清空,再次开启定位是需要重新传递监听回调 + */ + public void stopLocation() { + isLocation = false; + LogUtils.w("停止GPS定位"); + if (locationListenerList != null) { + for (GPSLocationListener l : locationListenerList) { + if (l != null) { + l.stopLocation(); + } + } + removeGPSLocationListenerAll(); + } + if (locationManager != null) { + if (gpsListener != null) { + locationManager.removeGpsStatusListener(gpsListener); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (gnssStatusCallback != null) { + locationManager.unregisterGnssStatusCallback(gnssStatusCallback); + } + } + if (locationListener != null) { + locationManager.removeUpdates(locationListener); + } + } + locationListener = null; + gpsListener = null; + } + + /** + * 注销某个位置监听 + * + * @param gpsLocationListener 监听实例对象 + */ + public void removeGPSLocationListener(GPSLocationListener gpsLocationListener) { + if (gpsLocationListener == null) return; + if (locationListenerList == null) return; + locationListenerList.remove(gpsLocationListener); + } + + /** + * 注销所有位置监听 + */ + public void removeGPSLocationListenerAll() { + if (locationListenerList == null) return; + locationListenerList.clear(); + } + + @SuppressLint("MissingPermission") + private class MyGPSListener implements GpsStatus.Listener { + //GPS状态发生变化时触发 + @Override + public void onGpsStatusChanged(int event) { + //获取当前状态 + GpsStatus gpsstatus = locationManager.getGpsStatus(null); + switch (event) { + //第一次定位时的事件 + case GpsStatus.GPS_EVENT_FIRST_FIX: + break; + //开始定位的事件 + case GpsStatus.GPS_EVENT_STARTED: + break; + //发送GPS卫星状态事件 + case GpsStatus.GPS_EVENT_SATELLITE_STATUS: + if (gpsstatus == null) return; + if (locationListenerList == null) return; + Iterable allSatellites = gpsstatus.getSatellites(); + if (allSatellites == null) return; + Iterator it = allSatellites.iterator(); + if (it == null) return; + int count = 0; + while (it.hasNext()) { + GpsSatellite next = it.next(); + if (next.getSnr() != 0) { + count++; + } + } +// LogUtils.v("搜索到:" + count + "颗卫星!"); + if (count == startCount) return; + for (GPSLocationListener l : locationListenerList) { + if (l != null) { + l.onScanSatellite(startCount, 0, 0); + } + } + break; + //停止定位事件 + case GpsStatus.GPS_EVENT_STOPPED: + LogUtils.w("Location", "GPS_EVENT_STOPPED"); + break; + } + } + } + + + @RequiresApi(api = Build.VERSION_CODES.N) + private GnssStatus.Callback getGnssStatusCallback() { + return new GnssStatus.Callback() { + @Override + public void onStarted() { + super.onStarted(); + } + + @Override + public void onSatelliteStatusChanged(GnssStatus status) { + if (locationListenerList == null) return; + int satelliteCount = status.getSatelliteCount(); + if (startCount != satelliteCount) { + startCount = satelliteCount; + //计算北东卫星数量 + int bdCount = 0; + //计算用于定位的卫星数量 + int locationCount = 0; + for (int i = 0; i < satelliteCount; i++) { + int constellationType = status.getConstellationType(i); + if (constellationType == GnssStatus.CONSTELLATION_BEIDOU) { + bdCount++; + } + if (status.usedInFix(i)) { + locationCount++; + } + } + for (GPSLocationListener l : locationListenerList) { + if (l != null) { + l.onScanSatellite(startCount, bdCount, locationCount); + } + } + if (RuanseeApplication.isPrintLog) { + LogUtils.d("搜索卫星", String.format("搜索到:%s颗卫星,北斗卫星:%s颗,用于定位的卫星:%s颗", startCount, bdCount, locationCount)); + } + } + } + }; + } + + public boolean isGPSPermission(Context context) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && + ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + // TODO: Consider calling + // ActivityCompat#requestPermissions + return false; + } + return true; + } + + private class MyLocationListener implements LocationListener { + + /** + * 位置发生改变 + * + * @param location + */ + @Override + public void onLocationChanged(Location location) { + if (locationListenerList == null) return; + for (GPSLocationListener l : locationListenerList) { + if (l != null) { + l.onLocationChanged(location); + } + } + } + + /** + * 定位状态发生改变 + * + * @param provider + * @param status + * @param extras + */ + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + /** + * 启用 定位模式 + * + * @param provider + */ + @Override + public void onProviderEnabled(String provider) { + + } + + /** + * 定位模式 被禁用 + * + * @param provider + */ + @Override + public void onProviderDisabled(String provider) { + + } + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/NotificationUtils.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/NotificationUtils.java new file mode 100644 index 0000000..180acdf --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/NotificationUtils.java @@ -0,0 +1,263 @@ +package com.ycgis.macall.personalcenter.util; + +import android.annotation.SuppressLint; +import android.app.AppOpsManager; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.net.Uri; +import android.os.Build; +import android.provider.Settings; + +import androidx.annotation.RequiresApi; +import androidx.core.app.NotificationCompat; + +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.v.activity.MainActivity; + +import org.greenrobot.eventbus.EventBus; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import static android.app.Notification.EXTRA_CHANNEL_ID; +import static android.provider.Settings.EXTRA_APP_PACKAGE; + +public class NotificationUtils { + private final static String CHANNEL_ID = "channel_id"; //通道渠道id + private final static String CHANEL_NAME = "chanel_name"; //通道渠道名称 + private final static int NOTIFICATION_SAMPLE = 1; + + private static final String CHECK_OP_NO_THROW = "checkOpNoThrow"; + private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION"; + + //调用该方法获取是否开启通知栏权限 + public static boolean isNotifyEnabled(Context context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + return isEnableV26(context); + } else { + return isEnabledV19(context); + } + } + + /** + * 8.0以下判断 + * + * @param context api19 4.4及以上判断 + * @return + */ + @RequiresApi(api = Build.VERSION_CODES.KITKAT) + private static boolean isEnabledV19(Context context) { + + AppOpsManager mAppOps = + (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); + + ApplicationInfo appInfo = context.getApplicationInfo(); + String pkg = context.getApplicationContext().getPackageName(); + int uid = appInfo.uid; + Class appOpsClass = null; + + try { + appOpsClass = Class.forName(AppOpsManager.class.getName()); + + Method checkOpNoThrowMethod = + appOpsClass.getMethod(CHECK_OP_NO_THROW, + Integer.TYPE, Integer.TYPE, String.class); + + Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION); + int value = (Integer) opPostNotificationValue.get(Integer.class); + + return ((Integer) checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) == + AppOpsManager.MODE_ALLOWED); + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + + /** + * 8.0及以上通知权限判断 + * + * @param context + * @return + */ + private static boolean isEnableV26(Context context) { + ApplicationInfo appInfo = context.getApplicationInfo(); + String pkg = context.getApplicationContext().getPackageName(); + int uid = appInfo.uid; + try { + NotificationManager notificationManager = (NotificationManager) + context.getSystemService(Context.NOTIFICATION_SERVICE); + Method sServiceField = notificationManager.getClass().getDeclaredMethod("getService"); + sServiceField.setAccessible(true); + Object sService = sServiceField.invoke(notificationManager); + + Method method = sService.getClass().getDeclaredMethod("areNotificationsEnabledForPackage" + , String.class, Integer.TYPE); + method.setAccessible(true); + return (boolean) method.invoke(sService, pkg, uid); + } catch (Exception e) { + return true; + } + } + + public static void setNotificationActivity(Context context) { + Intent localIntent = new Intent(); + //直接跳转到应用通知设置的代码: + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//8.0及以上 + localIntent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS); + //这种方案适用于 API 26, 即8.0(含8.0)以上可以用 + localIntent.putExtra(EXTRA_APP_PACKAGE, context.getPackageName()); + localIntent.putExtra(EXTRA_CHANNEL_ID, context.getApplicationInfo().uid); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0以上到8.0以下 + //这种方案适用于 API21——25,即 5.0——7.1 之间的版本可以使用 + localIntent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS); + localIntent.putExtra("app_package", context.getPackageName()); + localIntent.putExtra("app_uid", context.getApplicationInfo().uid); + } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {//4.4 + localIntent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + localIntent.addCategory(Intent.CATEGORY_DEFAULT); + localIntent.setData(Uri.parse("package:" + context.getPackageName())); + } else { + //4.4以下没有从app跳转到应用通知设置页面的Action,可考虑跳转到应用详情页面, + localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + if (Build.VERSION.SDK_INT >= 9) { + localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); + localIntent.setData(Uri.fromParts("package", context.getPackageName(), null)); + } else if (Build.VERSION.SDK_INT <= 8) { + localIntent.setAction(Intent.ACTION_VIEW); + localIntent.setClassName("com.android.settings", "com.android.setting.InstalledAppDetails"); + localIntent.putExtra("com.android.settings.ApplicationPkgName", context.getPackageName()); + } + } + context.startActivity(localIntent); + } + + public static void showNotification(Context context, String title, String message) { + NotificationChannel channel = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + //创建 通知通道 channelid和channelname是必须的(自己命名就好) + channel = new NotificationChannel(CHANNEL_ID, CHANEL_NAME, NotificationManager.IMPORTANCE_DEFAULT); + channel.enableLights(true);//是否在桌面icon右上角展示小红点 + channel.setLightColor(Color.GREEN);//小红点颜色 + channel.setShowBadge(false); //是否在久按桌面图标时显示此渠道的通知 + } + Notification notification; + // 打开程序后图标消失 + Intent intent = new Intent(context, MainActivity.class); + @SuppressLint("WrongConstant") + PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); + + //获取Notification实例 获取Notification实例有很多方法处理 在此我只展示通用的方法(虽然这种方式是属于api16以上,但是已经可以了,毕竟16以下的Android机很少了,如果非要全面兼容可以用) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + //向上兼容 用Notification.Builder构造notification对象 + notification = new Notification.Builder(context, CHANNEL_ID) + .setContentTitle(title) + .setContentText(message) + .setWhen(System.currentTimeMillis()) + .setSmallIcon(R.mipmap.icon_applogin) + .setColor(Color.parseColor("#FEDA26")) + .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.icon_applogin)) +// .setTicker("巴士门") + .setContentIntent(pendingIntent) + .build(); + } else { + //向下兼容 用NotificationCompat.Builder构造notification对象 + notification = new NotificationCompat.Builder(context) + .setContentTitle(title) + .setContentText(message) + .setWhen(System.currentTimeMillis()) + .setSmallIcon(R.mipmap.icon_applogin) + .setColor(Color.parseColor("#FEDA26")) + .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.icon_applogin)) +// .setTicker("巴士门") + .setContentIntent(pendingIntent) + .build(); + } + notification.flags |= Notification.FLAG_AUTO_CANCEL; + + //发送通知 + int notifiId = 1; + //创建一个通知管理器 + NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + if (notificationManager == null) return; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + notificationManager.createNotificationChannel(channel); + } +// EventBus.getDefault().post(new BackLogEvent(4)); + notificationManager.notify(notifiId, notification); + } + + public static void sendSimpleNotification(Context context, String title, String message) { + NotificationChannel channel = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + //创建 通知通道 channelid和channelname是必须的(自己命名就好) + channel = new NotificationChannel(CHANNEL_ID, CHANEL_NAME, NotificationManager.IMPORTANCE_DEFAULT); + channel.enableLights(true);//是否在桌面icon右上角展示小红点 + channel.setLightColor(Color.GREEN);//小红点颜色 + channel.setShowBadge(false); //是否在久按桌面图标时显示此渠道的通知 + } + + //创建点击通知时发送的广播 + Intent intent = new Intent(context, MainActivity.class); + PendingIntent pi = PendingIntent.getActivity(context, 0, intent, 0); + //创建删除通知时发送的广播 +// Intent deleteIntent = new Intent(context,MainActivity.class); + Notification notification; +// PendingIntent deletePendingIntent = PendingIntent.getService(context,0,deleteIntent,0); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + //创建通知 + notification = new Notification.Builder(context, CHANNEL_ID) + //设置通知左侧的小图标 + .setSmallIcon(R.mipmap.icon_applogin) + //设置通知标题 + .setContentTitle(title) + //设置通知内容 + .setContentText(message) + //设置点击通知后自动删除通知 + .setAutoCancel(true) + //设置显示通知时间 + .setShowWhen(true) + //设置通知右侧的大图标 +// .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_applogo)) + //设置点击通知时的响应事件 + .setContentIntent(pi) + //设置删除通知时的响应事件 +// .setDeleteIntent(deletePendingIntent) + .build(); + } else { + //向下兼容 用NotificationCompat.Builder构造notification对象 + notification = new NotificationCompat.Builder(context) + .setContentTitle(title) + .setContentText(message) + .setWhen(System.currentTimeMillis()) + .setSmallIcon(R.mipmap.icon_applogin) + .setColor(Color.parseColor("#FEDA26")) +// .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_applogo)) +// .setTicker("巴士门") + .setContentIntent(pi) + .build(); + } + + notification.flags |= Notification.FLAG_AUTO_CANCEL; + //创建一个通知管理器 + NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + if (notificationManager == null) return; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + notificationManager.createNotificationChannel(channel); + } +// EventBus.getDefault().post(new BackLogEvent(4)); + notificationManager.notify(NOTIFICATION_SAMPLE, notification); + //发送通知 +// nm.notify(NOTIFICATION_SAMPLE,notification); + } + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/ParamMap.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/ParamMap.java new file mode 100644 index 0000000..baf3419 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/ParamMap.java @@ -0,0 +1,43 @@ +package com.ycgis.macall.personalcenter.util; + +import com.rs.macall.androidx.basemodel.utils.StringUtil; + +import java.util.HashMap; +import java.util.Map; + +public class ParamMap { + private Map param ; + + public ParamMap(){ + param = new HashMap<>(); + } + + public ParamMap put(String key,String value){ + if (key == null ||value == null) return this; + param.put(key.trim(),value.trim()); + return this; + } + + + public String get(String key){ + return get(key,""); + } + public String get(String key,String defValue){ + if (key == null) return defValue; + return param.get(key.trim()); + } + + public Map apply(){ + return param; + } + + public String remove(String key){ + if (StringUtil.isNullOrEmpty(key))return ""; + return param.remove(key.trim()); + } + + public boolean isEmpty(){ + return param.isEmpty(); + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/PhoneValidateUtils.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/PhoneValidateUtils.java new file mode 100644 index 0000000..e8818fb --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/PhoneValidateUtils.java @@ -0,0 +1,15 @@ +package com.ycgis.macall.personalcenter.util; + +/** + * created by: Macall + * create time: 2023/11/22 14:43 + * copyright: @ruansee.com + * Describe: 验证 + */ +public class PhoneValidateUtils { + private static final String phoneNum = "^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$"; + + public static boolean isLegitimatePhoneNum(String beVerified){ + return beVerified.matches(phoneNum); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/ReadDeviceInfo.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/ReadDeviceInfo.java new file mode 100644 index 0000000..6e2d600 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/ReadDeviceInfo.java @@ -0,0 +1,423 @@ +package com.ycgis.macall.personalcenter.util; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageManager; +import android.os.Build; +import android.telephony.TelephonyManager; +import android.text.TextUtils; + +import androidx.annotation.RequiresApi; +import androidx.core.content.ContextCompat; + +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * created by: Macall + * create time: 2024/3/7 11:51 + * copyright: @ruansee.com + * Describe: + */ +public class ReadDeviceInfo { + private static final String TAG = "ReadDeviceInfo"; + + /** + * 获取默认的imei 一般都是IMEI 1 + * + * @param context + * @return + */ + public static String getIMEI1(Context context) { + //优先获取IMEI(即使是电信卡) 不行的话就获取MEID + return getImeiOrMeid(context, 0); + + } + + /** + * 获取imei2 + * + * @param context + * @return + */ + public static String getIMEI2(Context context) { + //imei2必须与 imei1不一样 + String imeiDefault = getIMEI1(context); + if (TextUtils.isEmpty(imeiDefault)) { + //默认的 imei 竟然为空,说明权限还没拿到,或者是平板 + //这种情况下,返回 imei2也应该是空串 + return ""; + } + + //注意,拿第一个 IMEI 是传0,第2个 IMEI 是传1,别搞错了 + String imei1 = getImeiOrMeid(context, 0); + String imei2 = getImeiOrMeid(context, 1); + //sim 卡换卡位时,imei1与 imei2有可能互换,而 imeidefault 有可能不变 + if (!TextUtils.equals(imei2, imeiDefault)) { + //返回与 imeiDefault 不一样的 + return imei2; + } + if (!TextUtils.equals(imei1, imeiDefault)) { + return imei1; + } + return ""; + } + + + //由于Android10以后无法根据卡槽获取,这里可以利用反射的方式获取 +//type : 0 (卡1),1(卡2) + public static String getIMSI(Context context, int type) { + String imsi = ""; + try { + //Android 6.0 以后需要获取动态权限 检查权限 + if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { + return imsi; + } + TelephonyManager manager = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); + imsi = getImsi(manager, type); + LogUtils.d("sim", "getIMSI: " + type + ": " + imsi); + if (StringUtil.isNullOrEmpty(imsi)) { + imsi = manager.getSubscriberId(); + } + return imsi; + } catch (Throwable e) { + e.getMessage(); + return ""; + } + } + + //由于Android10以后无法根据卡槽获取,这里可以利用反射的方式获取 +//type : 0 (卡1),1(卡2) + @RequiresApi(api = Build.VERSION_CODES.O) + public static String getIMEI(Context context) { + String imsi = ""; + try { + //Android 6.0 以后需要获取动态权限 检查权限 + if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { + return imsi; + } + TelephonyManager manager = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); + return manager.getImei(); + } catch (Throwable e) { + e.getMessage(); + return ""; + } + } + + + /** + * @param context + * @return + */ + @SuppressLint("MissingPermission") + public static String getIMEIOut(Context context) { + + String imei = ""; + + //Android 6.0 以后需要获取动态权限 检查权限 + if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { + return imei; + } + + try { + TelephonyManager manager = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); + if (manager != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {// android 8 即以后建议用getImei 方法获取 不会获取到MEID + Method method = manager.getClass().getMethod("getDeviceId", int.class); + imei = (String) method.invoke(manager, 0); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + //5.0的系统如果想获取MEID/IMEI1/IMEI2 ----framework层提供了两个属性值“ril.cdma.meid"和“ril.gsm.imei"获取 + imei = manager.getDeviceId(); + //如果获取不到 就调用 getDeviceId 方法获取 + + } else {//5.0以下获取imei/meid只能通过 getDeviceId 方法去取 + imei = manager.getDeviceId(); + } + return imei; + } + return ""; + } catch (Exception e) { + e.getMessage(); + return ""; + } + } + + // 反射实现 + @SuppressLint("SoonBlockedPrivateApi") + public static String getImsi(TelephonyManager telMgr, int type) { + Method getImsiMethod; + try { + getImsiMethod = telMgr.getClass().getDeclaredMethod("getSubscriberId", int.class); + return (String) getImsiMethod.invoke(telMgr, type); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + return ""; + } + } + + /** + * 获取 Imei/Meid 优先获取IMEI(即使是电信卡) 不行的话就获取MEID + *

+ * 如果装有CDMA制式的SIM卡(电信卡) ,在Android 8 以下 只能获取MEID ,无法获取到该卡槽的IMEI + * 8及以上可以通过 #imei 方法获取IMEI 通过 #deviceId 方法获取的是MEID + * + * @param context + * @param slotId slotId为卡槽Id,它的值为 0、1; + * @return + */ + public static String getImeiOrMeid(Context context, int slotId) { + String imei = ""; + + //Android 6.0 以后需要获取动态权限 检查权限 + if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { + return imei; + } + + try { + TelephonyManager manager = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); + if (manager != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {// android 8 即以后建议用getImei 方法获取 不会获取到MEID + Method method = manager.getClass().getMethod("getImei", int.class); + imei = (String) method.invoke(manager, slotId); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + //5.0的系统如果想获取MEID/IMEI1/IMEI2 ----framework层提供了两个属性值“ril.cdma.meid"和“ril.gsm.imei"获取 + imei = getSystemPropertyByReflect("ril.gsm.imei"); + //如果获取不到 就调用 getDeviceId 方法获取 + + } else {//5.0以下获取imei/meid只能通过 getDeviceId 方法去取 + } + } + } catch (Exception e) { + e.getMessage(); + } + + if (TextUtils.isEmpty(imei)) { + imei = getDeviceId(context, slotId); + } + return imei; + } + + + /** + * 仅获取 Imei 如果获取到的是meid 或空 均返回空字符串 + * + * @param slotId slotId为卡槽Id,它的值为 0、1; + * @return + */ + public static String getImeiOnly(Context context, int slotId) { + String imei = ""; + + //Android 6.0 以后需要获取动态权限 检查权限 + if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { + return imei; + } + + try { + TelephonyManager manager = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); + if (manager != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {// android 8 即以后建议用getImei 方法获取 不会获取到MEID + Method method = manager.getClass().getMethod("getImei", int.class); + imei = (String) method.invoke(manager, slotId); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + //5.0的系统如果想获取MEID/IMEI1/IMEI2 ----framework层提供了两个属性值“ril.cdma.meid"和“ril.gsm.imei"获取 + imei = getSystemPropertyByReflect("ril.gsm.imei"); + //如果获取不到 就调用 getDeviceId 方法获取 + + } else {//5.0以下获取imei/meid只能通过 getDeviceId 方法去取 + imei = manager.getDeviceId(); + } + } + } catch (Exception e) { + e.getMessage(); + } + + if (TextUtils.isEmpty(imei)) { + String imeiOrMeid = getDeviceId(context, slotId); + //长度15 的是imei 14的是meid + if (!TextUtils.isEmpty(imeiOrMeid) && imeiOrMeid.length() >= 15) { + imei = imeiOrMeid; + } + } + + return imei; + } + + /** + * 仅获取 Meid 如果获取到的是imei 或空 均返回空字符串 + * 一般只有一个 meid 即获取到的二个是相同的 + * + * @param context + * @param slotId slotId为卡槽Id,它的值为 0、1; + * @return + */ + public static String getMeidOnly(Context context, int slotId) { + String meid = ""; + //Android 6.0 以后需要获取动态权限 检查权限 + if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { + return meid; + } + try { + TelephonyManager manager = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); + if (manager != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {// android 8 即以后建议用getMeid 方法获取 不会获取到Imei + Method method = manager.getClass().getMethod("getMeid", int.class); + meid = (String) method.invoke(manager, slotId); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + //5.0的系统如果想获取MEID/IMEI1/IMEI2 ----framework层提供了两个属性值“ril.cdma.meid"和“ril.gsm.imei"获取 + meid = getSystemPropertyByReflect("ril.cdma.meid"); + //如果获取不到 就调用 getDeviceId 方法获取 + + } else {//5.0以下获取imei/meid只能通过 getDeviceId 方法去取 + } + } + } catch (Exception e) { + } + + if (TextUtils.isEmpty(meid)) { + String imeiOrMeid = getDeviceId(context, slotId); + //长度15 的是imei 14的是meid + if (imeiOrMeid.length() == 14) { + meid = imeiOrMeid; + } + } + return meid; + } + + + private static String getSystemPropertyByReflect(String key) { + try { + @SuppressLint("PrivateApi") + Class clz = Class.forName("android.os.SystemProperties"); + Method getMethod = clz.getMethod("get", String.class, String.class); + return (String) getMethod.invoke(clz, key, ""); + } catch (Exception e) {/**/} + return ""; + } + + /** + * 获取 IMEI/MEID + * + * @param context 上下文 + * @return 获取到的值 或者 空串"" + */ + public static String getDeviceId(Context context) { + String imei = ""; + //Android 6.0 以后需要获取动态权限 检查权限 + if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { + return imei; + } + + // 1. 尝试通过系统api获取imei + imei = getDeviceIdFromSystemApi(context); + if (TextUtils.isEmpty(imei)) { + imei = getDeviceIdByReflect(context); + } + return imei; + } + + /** + * 获取 IMEI/MEID + * + * @param context 上下文 + * @param slotId slotId为卡槽Id,它的值为 0、1; + * @return 获取到的值 或者 空串"" + */ + public static String getDeviceId(Context context, int slotId) { + String imei = ""; + // 1. 尝试通过系统api获取imei + imei = getDeviceIdFromSystemApi(context, slotId); + if (TextUtils.isEmpty(imei)) { + imei = getDeviceIdByReflect(context, slotId); + } + return imei; + } + + /** + * 调用系统接口获取 IMEI/MEID + *

+ * Android 6.0之后如果用户不允许通过 {@link Manifest.permission#READ_PHONE_STATE} 权限的话, + * 那么是没办法通过系统api进行获取 IMEI/MEID 的,但是可以通过{@linkplain #getDeviceIdByReflect(Context)} 反射}绕过权限进行获取 + * + * @param context 上下文 + * @return 获取到的值 或者 空串"" + */ + public static String getDeviceIdFromSystemApi(Context context, int slotId) { + String imei = ""; + try { + TelephonyManager telephonyManager = + (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); + if (telephonyManager != null) { + imei = telephonyManager.getDeviceId(slotId); + } + } catch (Throwable e) { + } + return imei; + } + + public static String getDeviceIdFromSystemApi(Context context) { + String imei = ""; + try { + TelephonyManager telephonyManager = + (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); + if (telephonyManager != null) { + imei = telephonyManager.getDeviceId(); + } + } catch (Throwable e) { + } + return imei; + } + + + /** + * 反射获取 IMEI/MEID + *

+ * Android 6.0之后如果用户不允许通过 {@link Manifest.permission#READ_PHONE_STATE} 权限的话, + * 那么是没办法通过系统api进行获取 IMEI/MEID 的,但是可以通过这个反射来尝试绕过权限进行获取 + * + * @param context 上下文 + * @return 获取到的值 或者 空串"" + */ + public static String getDeviceIdByReflect(Context context) { + try { + TelephonyManager tm = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); + if (Build.VERSION.SDK_INT >= 21) { + Method simMethod = TelephonyManager.class.getDeclaredMethod("getDefaultSim"); + Object sim = simMethod.invoke(tm); + Method method = TelephonyManager.class.getDeclaredMethod("getDeviceId", int.class); + return method.invoke(tm, sim).toString(); + } else { + Class clazz = Class.forName("com.android.internal.telephony.IPhoneSubInfo"); + Method subInfoMethod = TelephonyManager.class.getDeclaredMethod("getSubscriberInfo"); + subInfoMethod.setAccessible(true); + Object subInfo = subInfoMethod.invoke(tm); + Method method = clazz.getDeclaredMethod("getDeviceId"); + return method.invoke(subInfo).toString(); + } + } catch (Throwable e) { + e.printStackTrace(); + } + return ""; + } + + /** + * 反射获取 deviceId + * + * @param context + * @param slotId slotId为卡槽Id,它的值为 0、1; + * @return + */ + public static String getDeviceIdByReflect(Context context, int slotId) { + try { + TelephonyManager tm = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); + Method method = tm.getClass().getMethod("getDeviceId", int.class); + return method.invoke(tm, slotId).toString(); + } catch (Throwable e) { + } + return ""; + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/SearchHistoryUtils.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/SearchHistoryUtils.java new file mode 100644 index 0000000..1b3e928 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/SearchHistoryUtils.java @@ -0,0 +1,76 @@ +package com.ycgis.macall.personalcenter.util; + +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; + + +/** + * created by: Macall + * create time: 2022/12/5 15:41 + * copyright: @ruansee.com + * Describe: + */ +public class SearchHistoryUtils { + + public static final String SEARCH_HISTORY = "searchHistory"; + + /** + * 添加搜索记录 + * @param search 搜索内容 + */ + public static void addHistory(String search) { + if (StringUtil.isNullOrEmpty(search))return; + String searchHistory = RuanseeApplication.getStringValue(SEARCH_HISTORY, ""); + if (StringUtil.hasContent(searchHistory)) { + String nowSearchHistory = search + "," + searchHistory; +// StringBuilder builder = new StringBuilder(); +// String sp = ","; +// String[] split = searchHistory.split(","); +// builder.append(search); +// for (int i = 0; i < split.length; i++) { +// if (split[i].equals(search)){ +// continue; +// } +// builder.append(sp); +// builder.append(split[i]); +// } + RuanseeApplication.saveData(SEARCH_HISTORY, nowSearchHistory); + return; + } + RuanseeApplication.saveData(SEARCH_HISTORY, search); + } + + public static String[] getListHistory() { + String[] searchArr = null; + String searchHistory = RuanseeApplication.getStringValue(SEARCH_HISTORY, ""); + if (StringUtil.hasContent(searchHistory)) { + String[] split = searchHistory.split(","); + StringBuilder builder = new StringBuilder(); + if (split.length > 8) { + searchArr = new String[8]; + for (int i = 0; i < 8; i++) { + searchArr[i] = split[i]; + } + searchHistory = builder.toString(); + RuanseeApplication.saveData(SEARCH_HISTORY, searchHistory); + } else { + searchArr = split; + } + } + return searchArr; + } + + public static void getCancelHistory() { + RuanseeApplication.cleanStringValue(SEARCH_HISTORY); + } + + /** + * 是否存在历史记录 + * @return true 存在 false 不存在 + */ + public static boolean isHistory(){ + String searchHistory = RuanseeApplication.getStringValue(SEARCH_HISTORY, ""); + return StringUtil.hasContent(searchHistory); + + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/ToThirdPartyAppUtils.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/ToThirdPartyAppUtils.java new file mode 100644 index 0000000..dc25965 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/ToThirdPartyAppUtils.java @@ -0,0 +1,368 @@ +package com.ycgis.macall.personalcenter.util; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.Context; +import android.content.Intent; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.CheckBox; + +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleObserver; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.OnLifecycleEvent; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.m.adapterbean.AppBean; +import com.ycgis.macall.personalcenter.m.adapterbean.AppInfoBean; +import com.ycgis.macall.personalcenter.m.adapterbean.MessageBean; +import com.ycgis.macall.personalcenter.m.enumbean.AppOpenType; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.callback.SelectReturnCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.v.activity.ApplicationGuideActivity; +import com.ycgis.macall.personalcenter.v.activity.FrequentlyQuestionsActivity; +import com.ycgis.macall.personalcenter.v.activity.MsgDetailsActivity; +import com.ycgis.macall.personalcenter.v.activity.OpenAppActivity; +import com.ycgis.macall.personalcenter.v.activity.OpinionsSuggestionsActivity; +import com.ycgis.macall.personalcenter.v.activity.WorkbenchCenterActivity; +import com.ycgis.macall.personalcenter.v.activity.applyfo.ApplyForMainActivity; +import com.ycgis.macall.personalcenter.v.activity.travel.TravelAssistantActivity; + +import org.jetbrains.annotations.NotNull; + +import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.Map; + +import okhttp3.MediaType; +import okhttp3.RequestBody; + +/** + * created by: Macall + * create time: 2022/12/3 16:21 + * copyright: @ruansee.com + * Describe: 跳转第三方应用工具类 + */ +public class ToThirdPartyAppUtils implements LifecycleObserver { + private final static String TAG = "ToThirdPartyAppUtils"; + //应用市场 + private final static String APP_MARKET_PK = "com.sixin.police.market"; + + private WeakReference contextWeakReference; + private Dialog insertTips; + private Dialog lllAppTitle; + + public ToThirdPartyAppUtils(Context context) { + contextWeakReference = new WeakReference<>(context); + } + + /** + * 该方法不需要手动调用 3 盒 + * 宿主执行了onDestroy时 会分发该事件 + * 使用时请在宿主(Activity 或 Fragment ) 中调用如下代码,调用后当 宿主执行什么周期方法 onDestroy 该方法自动被调用 + * { getLifecycle().addObserver(locationGPSManage) } + */ + @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) + void onDestroy(@NotNull LifecycleOwner owner) { + contextWeakReference.clear(); + contextWeakReference = null; + } + + public void skipApp(AppInfoBean dataItem, AppOpenType openType) { + if (contextWeakReference == null) return; + if (interceptJump(String.valueOf(dataItem.getId()), dataItem.getName(), AppOpenType.LOGIN.getName())) + return; + AppBean bean = new AppBean(); + bean.setAppType(String.valueOf(dataItem.getType())); + bean.setLinkUrl(dataItem.getLink()); + bean.setClientSecret(dataItem.getClientSecret()); + bean.setClientId(dataItem.getClientId()); + bean.setAppName(dataItem.getName()); + bean.setOperationName(dataItem.getOperationPerson()); + bean.setOperationPhone(dataItem.getPhoneNumber()); + skipLevel(bean, openType); + } + + public void skipApp(AppBean dataItem) { + if (contextWeakReference == null) return; + if (interceptJump(dataItem.getId(), dataItem.getAppName(), AppOpenType.LOGIN.getName())) + return; + skipLevel(dataItem, AppOpenType.LOGIN); + } + + private boolean interceptJump(String appId, String appName, String operatorType) { + if (contextWeakReference == null) return true; + Context context = contextWeakReference.get(); + if (context == null) return true; + if (StringUtil.isNullOrEmpty(appName)) { + ToastUtil.centered(context, "应用错误!"); + return true; + } + //通讯录暂时无数据 57 + if ("更多应用".equals(appName)) { + context.startActivity(new Intent(context, WorkbenchCenterActivity.class)); +// addClickCount(appId,appName, operatorType); + return true; + }//应用申请 + if ("应用申请".equals(appName)) { + context.startActivity(new Intent(context, ApplyForMainActivity.class)); + addClickCount(appId, appName, operatorType); + return true; + }//差旅助手 + if ("差旅助手".equals(appName)) { + context.startActivity(new Intent(context, TravelAssistantActivity.class)); + addClickCount(appId, appName, operatorType); + return true; + } + if ("应用指南".equals(appName)) { + context.startActivity(new Intent(context, ApplicationGuideActivity.class)); +// addClickCount(appId, appName, operatorType); + return true; + } + if ("常见问题".equals(appName)) { + context.startActivity(new Intent(context, FrequentlyQuestionsActivity.class)); +// addClickCount(appId, appName, operatorType); + return true; + } + if ("意见反馈".equals(appName)) { + context.startActivity(new Intent(context, OpinionsSuggestionsActivity.class)); +// addClickCount(appId, appName, operatorType); + return true; + } + return false; + } + + public void skipLevel(AppBean bean, AppOpenType openType) { + if (contextWeakReference == null) return; + Context context = contextWeakReference.get(); + if ("3".equals(bean.getAppType())) { + //原生应用 + FileUtils.startAPP(context, bean.getLinkUrl(), message -> { + if (!message) { + if (contextWeakReference == null) return; + Context context1 = contextWeakReference.get(); + showInstallationTips(context1); + } + }); + } else { + Intent intent = new Intent(context, OpenAppActivity.class); + intent.putExtra(OpenAppActivity.paramKey1, bean.getClientId()); + intent.putExtra(OpenAppActivity.paramKey2, bean.getClientSecret()); + intent.putExtra(OpenAppActivity.paramKey3, bean.getLinkUrl()); + intent.putExtra(OpenAppActivity.paramKey9, bean.getAppName()); + intent.putExtra(OpenAppActivity.paramKey10, bean.getOperationName()); + intent.putExtra(OpenAppActivity.paramKey11, bean.getOperationPhone()); + if ("Ⅲ类应用".equals(bean.getNetworkType())) {//三类应用 + //弹出提示框 + if (!RuanseeApplication.isShowIIIAppTitle) { + showIIIAppTitle(context, intent, bean.getId(), bean.getAppName(), openType.getName()); + return; + } + } + context.startActivity(intent); + } + addClickCount(bean.getId(), bean.getAppName(), openType.getName()); + } + + /*public void skipLevel(AppBean bean, AppOpenType openType) { + if (contextWeakReference == null) return; + Context context = contextWeakReference.get(); + if ("3".equals(bean.getAppType())) { + //原生应用 + FileUtils.startAPP(context, bean.getLinkUrl(), new SelectReturnCallback() { + @Override + public void returnMsg(Boolean message) { + if (!message) { + if (contextWeakReference == null) return; + Context context = contextWeakReference.get(); + showInstallationTips(context); + } + } + }); + } else { + Intent intent = new Intent(context, OpenAppActivity.class); + intent.putExtra(OpenAppActivity.paramKey1, bean.getClientId()); + intent.putExtra(OpenAppActivity.paramKey2, bean.getClientSecret()); + intent.putExtra(OpenAppActivity.paramKey3, bean.getLinkUrl()); + intent.putExtra(OpenAppActivity.paramKey9, bean.getAppName()); + intent.putExtra(OpenAppActivity.paramKey10, bean.getOperationName()); + intent.putExtra(OpenAppActivity.paramKey11, bean.getOperationPhone()); + if ("Ⅲ类应用".equals(bean.getNetworkType())) {//三类应用 + //弹出提示框 + if (!RuanseeApplication.isShowIIIAppTitle) { + showIIIAppTitle(context, intent,bean.getId()); + return; + } + } + context.startActivity(intent); + } + addClickCount(bean.getId(),bean.getAppName(),openType.getName()); + }*/ + + private void addClickCount(String appId, String appName, String operatorType) { + Map param = new HashMap<>(); + param.put("appId", appId); + param.put("appName", appName); + param.put("operatorName", RuanseeApplication.getUserData().getUserName()); + param.put("operatorPoliceNumber", RuanseeApplication.getUserData().getUserCode()); + param.put("operatorIdCard", RuanseeApplication.getUserData().getIdCardNum()); + param.put("deptId", RuanseeApplication.getUserData().getDeptCode()); + param.put("deptName", RuanseeApplication.getUserData().getDeptName()); + param.put("type", operatorType); + String url = "http://192.168.43.183:8081/wzt/app/v1/zamh/addOperationRecords"; + + Object appId1 = param.get("appId"); + if (appId1 instanceof Long){ + long id = (long) appId1; + }else if(appId1 instanceof Integer) { + int id = (int) appId1; + } + +// MediaType mediaType = MediaType.parse("application/json;charset=utf-8"); + MediaType mediaType = MediaType.Companion.parse("application/json;charset=utf-8"); + RequestBody stringBody = RequestBody.Companion.create(new Gson().toJson(param), mediaType); + ApiModel.requestIO(RetrofitService.getBaseInstance().saveAppOperationLog(stringBody), new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(TAG, msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + LogUtils.w(TAG, result.toString()); + } + }); +// ApiModel.requestIO(RetrofitService.getBaseInstance().addClickCount(TypConversion.strToLong(appId)), new BaseRequestCallback() { +// @Override +// public void onRequestFailure(String msg) { +// LogUtils.e(TAG, msg); +// } +// +// @Override +// public void onRequestSuccess(JsonObject result) { +// LogUtils.w(TAG, result.toString()); +// } +// }); + } + + private void showInstallationTips(Context context) { + if (insertTips == null) { + View view = LayoutInflater.from(context).inflate(R.layout.dialog_not_insert_app, null, false); + insertTips = new AlertDialog.Builder(context) + .setView(view) + .create(); + } + insertTips.show(); + //提示内容 +// insertTips.findViewById(R.id.tv_msg); + insertTips.findViewById(R.id.btn_determine).setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + insertTips.dismiss(); + } + }); + insertTips.findViewById(R.id.btn_go_insert).setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + insertTips.dismiss(); + FileUtils.startAPP(context, APP_MARKET_PK, null); + } + }); + } + + private void showIIIAppTitle(Context context, Intent intent, String id, String appName, String operatorType) { + if (lllAppTitle == null) { + View view = LayoutInflater.from(context).inflate(R.layout.dialog_show_lll_app_title, null, false); + lllAppTitle = new AlertDialog.Builder(context) + .setView(view) + .create(); + } + lllAppTitle.show(); + lllAppTitle.findViewById(R.id.btn_cancel).setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + lllAppTitle.dismiss(); + } + }); + lllAppTitle.findViewById(R.id.btn_confirm_open).setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + lllAppTitle.dismiss(); + CheckBox checkBox = lllAppTitle.findViewById(R.id.checkBox); + RuanseeApplication.isShowIIIAppTitle = checkBox.isChecked(); + context.startActivity(intent); + addClickCount(id, appName, operatorType); + } + }); + } + + //扫描二维码 + + // /** +// * 消息列表跳转执行此方法 +// * @param dataItem +// */ + public void skipReadMsg(MessageBean dataItem) { + if (contextWeakReference == null) return; + Context context = contextWeakReference.get(); + ApiModel.uploadOperationLog("3","3","用户查看消息"); + if (dataItem.getAppExhibition() == 1) { + Intent intent = new Intent(context, MsgDetailsActivity.class); + intent.putExtra("msgData",dataItem); + context.startActivity(intent); + } else { + Intent intent = new Intent(context, OpenAppActivity.class); + intent.putExtra(OpenAppActivity.paramKey1, dataItem.getClientId()); + intent.putExtra(OpenAppActivity.paramKey2, dataItem.getClientSecret()); + intent.putExtra(OpenAppActivity.paramKey3, dataItem.getAppLinkUrl()); + intent.putExtra(OpenAppActivity.paramKey4, dataItem.getMsgId()); + intent.putExtra(OpenAppActivity.paramKey5, dataItem.getMsgType()); + intent.putExtra(OpenAppActivity.paramKey9, dataItem.getAppName()); + intent.putExtra(OpenAppActivity.paramKey6, "readMessage"); +// intent.putExtra(OpenAppActivity.paramKey10, dataItem.getOperationName()); +// intent.putExtra(OpenAppActivity.paramKey11, dataItem.getOperationPhone()); + context.startActivity(intent); + } + if (!dataItem.isRead()){ + ApiModel.requestIO(RetrofitService.getBaseInstance().readMessage(dataItem.getId()), null); + } + addClickCount(dataItem.getApplicationId(), dataItem.getAppName(), AppOpenType.READ_MESSAGE.getName()); + } + +// /** +// * 从搜索结果跳转执行此方法 +// * @param id id +// * @param appId 应用注册ID +// * @param secret 秘钥 +// * @param dataJson Json数据 +// * @param url 应用链接 +// * @param searchType 搜索类型(car/person) +// */ +// public void skipSearchData(String id,String name,String appId,String secret,String url,String searchType,String dataJson,String ywryName,String phone) { +// if (contextWeakReference == null) return; +// Context context = contextWeakReference.get(); +// Intent intent = new Intent(context, OpenAppActivity.class); +// intent.putExtra(OpenAppActivity.paramKey1, appId); +// intent.putExtra(OpenAppActivity.paramKey2, secret); +// intent.putExtra(OpenAppActivity.paramKey3, url); +// intent.putExtra(OpenAppActivity.paramKey6,"search"); +// intent.putExtra(OpenAppActivity.paramKey7, searchType); +// intent.putExtra(OpenAppActivity.paramKey8, dataJson); +// intent.putExtra(OpenAppActivity.paramKey9,name); +// intent.putExtra(OpenAppActivity.paramKey10, ywryName); +// intent.putExtra(OpenAppActivity.paramKey11,phone); +// context.startActivity(intent); +// addClickCount(id,name,AppOpenType.SEARCH.getName()); +// } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/UriUtils.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/UriUtils.java new file mode 100644 index 0000000..23a399c --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/UriUtils.java @@ -0,0 +1,237 @@ +package com.ycgis.macall.personalcenter.util; + +import android.annotation.SuppressLint; +import android.content.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; + +import androidx.core.content.FileProvider; + +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.ycgis.macall.personalcenter.R; + +import java.io.File; + +/** + * Created by Administrator on 2017/9/4. + * TODO 请注意 7.0以上版本需要配置 FileProvider 并将 配置的 authorities 值添加到 string.xml 中,key 值为 ”fileProviderName“ + */ +public class UriUtils { + + public static Intent getPhotoIntent(Context context, File file) { + Intent intent = new Intent(); + // 指定开启系统相机的Action + intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); + Uri photoURI; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + //如果是7.0及以上的系统使用FileProvider的方式创建一个Uri + LogUtils.e("相机权限", "系统版本大于7.0"); + //TODO 请注意 7.0以上版本需要配置 FileProvider + photoURI = FileProvider.getUriForFile(context, context.getString(R.string.fileProviderName), file); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + } else { + //7.0以下使用这种方式创建一个Uri + photoURI = Uri.fromFile(file); + } + intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); + return intent; + } + + /** + * 获取Uri + * @param context + * @param file + * @return + */ + public static Uri getUri(Context context, File file) { + if (context == null || file == null) return null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + //如果是7.0及以上的系统使用FileProvider的方式创建一个Uri + LogUtils.e("相机权限", "系统版本大于7.0"); + return FileProvider.getUriForFile(context, context.getString(R.string.fileProviderName), file); + } + //7.0以下使用这种方式创建一个Uri + return Uri.fromFile(file); + } + + /** + * 根据Uri获取图片的绝对路径 + * + * @param context 上下文对象 + * @param uri 图片的Uri + * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null + */ + public static String getRealPathFromUri(Context context, Uri uri) { + int sdkVersion = Build.VERSION.SDK_INT; + if (sdkVersion >= 19) { // api >= 19 + return getRealPathFromUriAboveApi19(context, uri); + } else { // api < 19 + return getRealPathFromUriBelowAPI19(context, uri); + } + } + + /** + * 适配api19以下(不包括api19),根据uri获取图片的绝对路径 + * + * @param context 上下文对象 + * @param uri 图片的Uri + * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null + */ + private static String getRealPathFromUriBelowAPI19(Context context, Uri uri) { + return getDataColumn(context, uri, null, null); + } + + /** + * 适配api19及以上,根据uri获取图片的绝对路径 + * + * @param context 上下文对象 + * @param uri 图片的Uri + * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null + */ + @SuppressLint("NewApi") + private static String getRealPathFromUriAboveApi19(Context context, Uri uri) { + String filePath = null; + if (DocumentsContract.isDocumentUri(context, uri)) { + // 如果是document类型的 uri, 则通过document id来进行处理 + String documentId = DocumentsContract.getDocumentId(uri); + if (isMediaDocument(uri)) { // MediaProvider + // 使用':'分割 + String id = documentId.split(":")[1]; + + String selection = MediaStore.Images.Media._ID + "=?"; + String[] selectionArgs = {id}; + filePath = getDataColumn(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs); + } else if (isDownloadsDocument(uri)) { // DownloadsProvider + Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(documentId)); + filePath = getDataColumn(context, contentUri, null, null); + } + } else if ("content".equalsIgnoreCase(uri.getScheme())) { + // 如果是 content 类型的 Uri + filePath = getDataColumn(context, uri, null, null); + } else if ("file".equals(uri.getScheme())) { + // 如果是 file 类型的 Uri,直接获取图片对应的路径 + filePath = uri.getPath(); + } + return filePath; + } + + /** + * 获取数据库表中的 _data 列,即返回Uri对应的文件路径 + * + * @return + */ + private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { + String path = null; + + String[] projection = new String[]{MediaStore.Images.Media.DATA}; + Cursor cursor = null; + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); + if (cursor != null && cursor.moveToFirst()) { + int columnIndex = cursor.getColumnIndexOrThrow(projection[0]); + path = cursor.getString(columnIndex); + } + } catch (Exception e) { + e.printStackTrace(); + if (cursor != null) { + cursor.close(); + } + } + return path; + } + + /** + * @param uri the Uri to check + * @return Whether the Uri authority is MediaProvider + */ + private static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + + /** + * @param uri the Uri to check + * @return Whether the Uri authority is DownloadsProvider + */ + private static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + public static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + public static String getPath(final Context context, final Uri uri) { + + final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + + // DocumentProvider + if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { + // ExternalStorageProvider + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + if ("primary".equalsIgnoreCase(type)) { + return Environment.getExternalStorageDirectory() + "/" + split[1]; + } else { + return "/storage/" + split[0] + "/" + split[1]; + } + + // TODO handle non-primary volumes + } + // DownloadsProvider + else if (isDownloadsDocument(uri)) { + + final String id = DocumentsContract.getDocumentId(uri); + try { + final Uri contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + return getDataColumn(context, contentUri, null, null); + } catch (NumberFormatException e) { + return ""; + } + + } + // MediaProvider + else if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri = null; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + + final String selection = "_id=?"; + final String[] selectionArgs = new String[]{split[1]}; + + return getDataColumn(context, contentUri, selection, selectionArgs); + } + } + // MediaStore (and general) + else if ("content".equalsIgnoreCase(uri.getScheme())) { + return getDataColumn(context, uri, null, null); + } + // File + else if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + + return ""; + } + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/util/VibratorHelper.java b/app/src/main/java/com/ycgis/macall/personalcenter/util/VibratorHelper.java new file mode 100644 index 0000000..7fd7668 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/util/VibratorHelper.java @@ -0,0 +1,24 @@ +package com.ycgis.macall.personalcenter.util; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.Service; +import android.os.Vibrator; + +public class VibratorHelper { + + @SuppressLint("MissingPermission") + public static void Vibrate(final Activity activity, long milliseconds) { + Vibrator vibrator = (Vibrator) activity + .getSystemService(Service.VIBRATOR_SERVICE); + vibrator.vibrate(milliseconds); + } + + @SuppressLint("MissingPermission") + public static void Vibrate(final Activity activity, long[] pattern, + boolean isRepeat) { + Vibrator vibrator = (Vibrator) activity + .getSystemService(Service.VIBRATOR_SERVICE); + vibrator.vibrate(pattern, isRepeat ? 1 : -1); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/AboutActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/AboutActivity.java new file mode 100644 index 0000000..ef1a908 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/AboutActivity.java @@ -0,0 +1,137 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.Bundle; + +import androidx.annotation.NonNull; + +import com.fri.libfriapkrecord.read.SignRecordTools; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityAboutBinding; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.rxjava.ResultObserver; +import com.ycgis.macall.personalcenter.p.rxjava.UpdateUiOnSubscribe; +import com.ycgis.macall.personalcenter.util.FileUtils; + +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.FileNotFoundException; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; + +import io.reactivex.Observable; +import io.reactivex.ObservableEmitter; +import io.reactivex.ObservableOnSubscribe; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; + +public class AboutActivity extends BaseViewBindActivity { + + @Override + protected ActivityAboutBinding getViewBinding() { + return ActivityAboutBinding.inflate(getLayoutInflater()); + } + + @Override + protected void init() { + + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void start() { + viewBinding.include.contentTitle.setText(R.string.about); + viewBinding.include.leftImage.setImageDrawable(getDrawables(R.drawable.back_cliener)); + viewBinding.include.titleleft.setOnClickListener(v -> finish()); + + String[] version = getVersion(); + viewBinding.aboutVersionNum.setText(version[0]); + viewBinding.aboutVersionName.setText("V " + version[1]); + String recordNumber = RuanseeApplication.getStringValue("NRRecordNumber"); + if (StringUtil.isNullOrEmpty(recordNumber)||recordNumber.contains("应用未备案")||recordNumber.contains("未获取")){ + //读取备案号 + String apkPath = getNativeApkPath(getApplicationContext()); + recordNumber = SignRecordTools.readNumbers(apkPath); + RuanseeApplication.saveData("NRRecordNumber",recordNumber); + } + viewBinding.tvBah.setText(String.format("全国注册备案号:%s",recordNumber)); +// jsdx(); + } + + //获取系统内APK文件路径 + public static String getNativeApkPath(@NonNull final Context context) { + String apkPath = null; + try { + final ApplicationInfo applicationInfo = context.getApplicationInfo(); + if (applicationInfo == null) { + return null; + } + apkPath = applicationInfo.sourceDir; + } catch (Throwable e) { + e.printStackTrace(); + } + return apkPath; + } + + private void jsdx() { + Observable.create(emitter -> { + String s = FileUtils.initFilePath(getContext()); + File file = new File(s); + if (!file.exists()){ + throw new FileNotFoundException("没有找到指定文件夹"); + } + long l = FileUtils.calculateFileSize(file); + emitter.onNext("缓存文件大小: "+FileUtils.formatFileSize(l, FileUtils.FileSizeFormType.M)); + emitter.onComplete(); + }).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new ResultObserver("") { + @Override + protected void onNext(String identifierKey, @NotNull Object data) { + ToastUtil.centered(getContext(),data.toString()); + } + + @Override + public void onError(@NotNull Throwable e) { + ToastUtil.centered(getContext(),e.getMessage()); + } + + @Override + protected void onComplete(String identifierKey) { + + } + }); + } + + + public String[] getVersion() { + try { + PackageManager manager = this.getPackageManager(); + PackageInfo info = manager.getPackageInfo(this.getPackageName(), 0); + return new String[]{String.valueOf(info.versionCode), info.versionName}; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/AppGuideDetailsActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/AppGuideDetailsActivity.java new file mode 100644 index 0000000..cb4fdd4 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/AppGuideDetailsActivity.java @@ -0,0 +1,257 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; + +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.listener.OnRefreshListener; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityAppGuideDetailsBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.AppGuideDetailsBean; +import com.ycgis.macall.personalcenter.m.adapterbean.AppInfoBean; +import com.ycgis.macall.personalcenter.p.app.AppCache; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.DownloadUtil; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.util.FileUtils; +import com.ycgis.macall.personalcenter.v.adapter.AppGuideDetailsAdapter; +import com.ycgis.macall.personalcenter.v.photoview.ShowPhotoDialog; + +import org.jetbrains.annotations.NotNull; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +/** + * 应用指南详情 + */ +public class AppGuideDetailsActivity extends BaseViewBindActivity { + private String appJson; + private AppInfoBean appBean; + private AppGuideDetailsAdapter adapter; + private ShowPhotoDialog showPhotoDialog; +// private LoadAppCenterImage loadAppCenterImage; + + @Override + protected ActivityAppGuideDetailsBinding getViewBinding() { + return ActivityAppGuideDetailsBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { +// setViewOnClickListener(viewBinding.baseTitle.titleleft); + GridLayoutManager manager = new GridLayoutManager(getContext(), 3); + viewBinding.rvAppList.setLayoutManager(manager); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + appJson = getIntent().getStringExtra("appJson"); + } + + @Override + protected void start() { + viewBinding.baseTitle.leftImage.setImageDrawable(getDrawables(R.drawable.back_cliener)); + viewBinding.baseTitle.contentTitle.setText("指南详情"); + viewBinding.baseTitle.titleleft.setOnClickListener(v -> finish()); + SmartRefreshLayoutHelp.setPullDownToRefresh(getContext(), viewBinding.srlRefresh); + viewBinding.srlRefresh.setOnRefreshListener(new OnRefreshListener() { + @Override + public void onRefresh(@NonNull @NotNull RefreshLayout refreshLayout) { + getDetailsList(); + } + }); + viewBinding.srlRefresh.autoRefresh(); + LinearLayoutManager manager = new LinearLayoutManager(getContext()); + manager.setOrientation(LinearLayoutManager.HORIZONTAL); + viewBinding.rvAppList.setLayoutManager(manager); + appBean = new Gson().fromJson(appJson, AppInfoBean.class); + setAppInfo(); + } + + private void setAppInfo() { + viewBinding.tvAppName.setText(appBean.getName()); + if (StringUtil.hasContent(appBean.getRemark())) { + viewBinding.tvAppIntroduction.setText("\t\t" + appBean.getRemark()); + } + viewBinding.tvCompany.setText(appBean.getServiceProvider()); + viewBinding.tvOperationName.setText(String.format("运维人员:%s", appBean.getOperationPerson())); + viewBinding.tvOperationLxdh.setText(String.format("联系电话:%s", appBean.getPhoneNumber())); + setImg(viewBinding.ivIcon, appBean.getIconUrl()); + + ApiModel.uploadOperationLog("3","3", " 查询应用:"+appBean.getName() +"指南"); + } + + private void setImg(ImageView img, String url) { + //图片加载自己实现 + Glide.with(img) + .load(url) + .placeholder(R.drawable.icon_error2) + .error(R.drawable.ic_load_imag_eerror) + .into(img); + } + + private void getDetailsList() { + ApiModel.request("getCZSCxq", RetrofitService.getBaseInstance().operationGuideList(String.valueOf(appBean.getId())), new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(TAG, msg); + List dataList = new ArrayList<>(); + AppGuideDetailsBean bean = new AppGuideDetailsBean(); + bean.setBaseType(-1); + bean.setBaseMessage(msg); + dataList.add(bean); + initData(dataList); + } + + @Override + public void onRequestSuccess(JsonObject result) { + LogUtils.w(TAG, result.toString()); + List dataList = new ArrayList<>(); + try { + JSONObject object = new JSONObject(result.toString()); + String code = TypConversion.getJsonStr(object, "code"); + if (code.equals("20041")) { + JSONArray data = TypConversion.getJSONArray(object, "data"); + if (data == null) { + AppGuideDetailsBean bean = new AppGuideDetailsBean(); + bean.setBaseType(0); + bean.setBaseMessage(TypConversion.getJsonStr(object, "msg")); + dataList.add(bean); + initData(dataList); + return; + } + Type type = new TypeToken>() { + }.getType(); + List list = new Gson().fromJson(data.toString(), type); + if (list == null || list.isEmpty()) { + AppGuideDetailsBean bean = new AppGuideDetailsBean(); + bean.setBaseType(0); + bean.setBaseMessage("暂未操作手册"); + dataList.add(bean); + initData(dataList); + return; + } + dataList.addAll(list); + for (AppGuideDetailsBean b : dataList) { + b.setBaseType(1); + } + initData(dataList); + } else { + AppGuideDetailsBean bean = new AppGuideDetailsBean(); + bean.setBaseType(0); + bean.setBaseMessage(TypConversion.getJsonStr(object, "msg")); + dataList.add(bean); + initData(dataList); + } + } catch (JSONException e) { + e.printStackTrace(); + AppGuideDetailsBean bean = new AppGuideDetailsBean(); + bean.setBaseType(-1); + bean.setBaseMessage(e.getMessage()); + dataList.add(bean); + initData(dataList); + } + } + }); + } + + private void initData(List dataList) { + viewBinding.srlRefresh.finishRefresh(); + if (adapter == null) { + adapter = new AppGuideDetailsAdapter(getContext(), dataList); + viewBinding.rvAppList.setAdapter(adapter); + adapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + AppGuideDetailsBean dataItem = adapter.getDataItem(pointer); + String imgUrl = AppCache.BASE_IMAGE_URL + dataItem.getFilePath(); + if (dataItem.getType() == 1) { + if (showPhotoDialog == null) { + showPhotoDialog = new ShowPhotoDialog(getContext(), R.style.MyDialogTheme); + } + if (StringUtil.hasContent(dataItem.getFilePath())) { + showPhotoDialog.show(imgUrl); + } + } else if (dataItem.getType() == 2) { + if (dataItem.getFilePath().endsWith(".mp4")) { + Intent intent = new Intent(getContext(), PlayVideosActivity.class); + intent.putExtra("url", imgUrl); + startActivity(intent); + return; + } + } else if (dataItem.getType() == 3) { + String filePath = dataItem.getFilePath(); + int i = filePath.lastIndexOf("/"); + String substring = filePath.substring(i + 1); + File file = new File(FileUtils.FILE_DIR, substring); + if (file.exists()) { + //打开文件 + FileUtils.openFileByPath(getActivity(), file.getAbsolutePath()); + } else { + //下载文件 + handlerFile(imgUrl); + } + } + } + }); + } else { + adapter.upData(dataList); + } + } + + private void handlerFile(String url) { + baseShowDialog("正在下载文件,请稍后..."); + DownloadUtil.get().download(url, FileUtils.FILE_DIR, "", new DownloadUtil.OnDownloadListener() { + @Override + public void onDownloadSuccess(File file) { + baseDismissDialog(); + ToastUtil.centered(getContext(), "文件下载成功!"); + if (file.exists()) { + //打开文件 + FileUtils.openFileByPath(getActivity(), file.getAbsolutePath()); + } + } + + @Override + public void onDownloading(int progress) { + + } + + @Override + public void onDownloadFailed(String msg) { + baseDismissDialog(); + ToastUtil.centered(getContext(), "文件下载失败!" + msg); + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/ApplicationGuideActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/ApplicationGuideActivity.java new file mode 100644 index 0000000..7f7d41e --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/ApplicationGuideActivity.java @@ -0,0 +1,361 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.KeyEvent; +import android.view.View; +import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; +import android.widget.LinearLayout; +import android.widget.PopupWindow; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.google.gson.Gson; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.utils.DimensionConvert; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.listener.OnLoadMoreListener; +import com.scwang.smart.refresh.layout.listener.OnRefreshListener; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityApplicationGuideBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.AppInfoBean; +import com.ycgis.macall.personalcenter.m.adapterbean.SelectAddressBean; +import com.ycgis.macall.personalcenter.m.requestbean.AppInfoModel; +import com.ycgis.macall.personalcenter.m.requestbean.BaseRequestModel; +import com.ycgis.macall.personalcenter.m.requestbean.PagingModel; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.callback.SelectReturnCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.v.adapter.ApplicationGuideAdapter; +import com.ycgis.macall.personalcenter.v.custom.SelectAddressPopupWindow; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import io.reactivex.Observable; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; + +/** + * 应用指南 + */ +public class ApplicationGuideActivity extends BaseViewBindActivity { + private ApplicationGuideAdapter adapter; + private int pageNum, pageSize = 10, totalCount; + private int refreshType = 0; + private String selectCode; + private String appName; + + private SelectAddressPopupWindow selectAddressPopupWindow; + + @Override + protected ActivityApplicationGuideBinding getViewBinding() { + return ActivityApplicationGuideBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + LinearLayoutManager manager = new LinearLayoutManager(getContext()); + manager.setOrientation(LinearLayoutManager.VERTICAL); + viewBinding.rvAppList.setLayoutManager(manager); + SmartRefreshLayoutHelp.setRefreshAndLoad(getContext(), viewBinding.srlRefresh); + setViewOnClickListener(viewBinding.btnSelect); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void start() { + viewBinding.tvSelectName.setText(RuanseeApplication.getUserData().getDepartmentName()); + selectCode = RuanseeApplication.getUserData().getDepartmentCode() + "00000000"; + viewBinding.baseTitle.leftImage.setImageDrawable(getDrawable(R.drawable.back_cliener)); + viewBinding.baseTitle.contentTitle.setText("应用指南"); + setViewOnClickListener(viewBinding.baseTitle.titleleft); + setViewOnClickListener(viewBinding.btnSelect); + viewBinding.search.editQuery.setImeOptions(EditorInfo.IME_ACTION_SEARCH); + queryEvent(); + refreshEvent(); + viewBinding.srlRefresh.autoRefresh(); + viewBinding.btnSelect.setClickable(false); + } + + private void refreshEvent() { + viewBinding.srlRefresh.setOnRefreshListener(new OnRefreshListener() { + @Override + public void onRefresh(@NonNull @NotNull RefreshLayout refreshLayout) { + pageNum = 1; + refreshType = 1; + viewBinding.srlRefresh.resetNoMoreData(); + getAppData(); + } + }); + viewBinding.srlRefresh.setOnLoadMoreListener(new OnLoadMoreListener() { + @Override + public void onLoadMore(@NonNull @NotNull RefreshLayout refreshLayout) { + if (pageNum * pageSize >= totalCount) { + viewBinding.srlRefresh.finishLoadMoreWithNoMoreData(); + return; + } + pageNum++; + refreshType = 2; + getAppData(); + } + }); + } + + private void queryEvent() { + viewBinding.search.editQuery.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + if (s == null || StringUtil.isNullOrEmpty(s.toString())) { + goneView(viewBinding.search.btnClean); + appName = null; + return; + } + visibleView(viewBinding.search.btnClean); + } + }); + viewBinding.search.btnClean.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + viewBinding.search.editQuery.setText(""); + goneView(viewBinding.search.btnClean); + appName = null; + } + }); + viewBinding.search.editQuery.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_SEARCH) { + appName = getEditText(viewBinding.search.editQuery); + viewBinding.srlRefresh.autoRefresh(); + return true; + } + return false; + } + }); + } + + @Override + protected void bindViewClick(View v) { + if (v.getId() == R.id.titleleft) { + finish(); + } else if (v.getId() == R.id.btn_select) { + if (RuanseeApplication.getUserData().getDepartmentCode().equals("3400")) { + showSelectAll(); + } else { + if (selectCode.startsWith("3400")) { + viewBinding.tvSelectName.setText(RuanseeApplication.getUserData().getDepartmentName()); + selectCode = RuanseeApplication.getUserData().getDepartmentCode() + "00000000"; + } else { + selectCode = "340000000000"; + viewBinding.tvSelectName.setText("省厅"); + } + viewBinding.srlRefresh.autoRefresh(); + } + viewBinding.btnSelect.setClickable(false); + } + } + + private void showSelectAll() { + showSelectAll(getActivity(), viewBinding.baseTitle.contentTitle, new PopupWindow.OnDismissListener() { + @Override + public void onDismiss() { + yanshishezhi(); + WindowManager.LayoutParams lp = getActivity().getWindow().getAttributes(); + lp.alpha = 1f; + getActivity().getWindow().setAttributes(lp); + } + }, new SelectReturnCallback() { + @Override + public void returnMsg(SelectAddressBean message) { + selectCode = message.getCode() + "00000000"; + viewBinding.tvSelectName.setText(message.getName()); + viewBinding.srlRefresh.autoRefresh(); + } + }); + } + + private AppInfoBean error(int type, String msg) { + AppInfoBean b = new AppInfoBean(); + b.setBaseType(type); + b.setBaseMessage(msg); + return b; + } + + private void getAppData() { +// ApiModel.request(RetrofitService.getBaseInstance().applicationPage(null, selectCode, pageNum, pageSize, appName, null), + ApiModel.request(RetrofitService.getBaseInstance().applicationCzsc(appName, selectCode, pageNum, pageSize), + new BaseRequestCallback>>() { + @Override + public void onRequestFailure(String msg) { + if (refreshType == 1) { + List beanList = new ArrayList<>(); + AppInfoBean bean = new AppInfoBean(); + bean.setBaseType(-1); + bean.setBaseMessage(msg); + beanList.add(bean); + initAppData(beanList); + viewBinding.srlRefresh.finishRefresh(); + } else if (refreshType == 2) { + viewBinding.srlRefresh.finishLoadMore(); + } + refreshType = 0; + ToastUtil.centered(getContext(), msg); + yanshishezhi(); + } + + @Override + public void onRequestSuccess(BaseRequestModel> result) { + LogUtils.w(TAG, result.toString()); + if (result.getCode() == 20041) { + PagingModel data = result.getData(); + totalCount = data.getCounts(); + List items = data.getItems(); + for (AppInfoBean b : items) { + b.setBaseType(1); + } + if (viewBinding.srlRefresh.isRefreshing()) { + viewBinding.srlRefresh.finishRefresh(); + if (items.isEmpty()) { + items.add(error(0, "暂无应用")); + } else { + if (pageSize * pageNum >= totalCount) { + viewBinding.srlRefresh.finishLoadMoreWithNoMoreData(); + } + } + initAppData(items); + } + if (viewBinding.srlRefresh.isLoading()) { + viewBinding.srlRefresh.finishLoadMore(); + if (!items.isEmpty()) { + adapter.addData(items); + if (pageSize * pageNum >= totalCount) { + viewBinding.srlRefresh.finishLoadMoreWithNoMoreData(); + } + } + } + } else { + if (viewBinding.srlRefresh.isRefreshing()) { + viewBinding.srlRefresh.finishRefresh(); + AppInfoBean error = error(-1, result.getMsg()); + List items = new ArrayList<>(); + items.add(error); + initAppData(items); + } + if (viewBinding.srlRefresh.isLoading()) { + viewBinding.srlRefresh.finishLoadMore(); + ToastUtil.centered(getContext(), result.getMsg()); + } + } + yanshishezhi(); + } + }); + } + + private void initAppData(List dataList) { + if (adapter == null) { + adapter = new ApplicationGuideAdapter(getContext(), dataList); + viewBinding.rvAppList.setAdapter(adapter); + adapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + if (adapter.getItemViewType(pointer) == 1) { + AppInfoBean dataItem = adapter.getDataItem(pointer); + Intent intent = new Intent(getContext(), AppGuideDetailsActivity.class); + intent.putExtra("appJson", new Gson().toJson(dataItem)); + startActivity(intent); + } + } + }); + } else { + adapter.upData(dataList); + } + } + + private void yanshishezhi() { + Observable.timer(800, TimeUnit.MILLISECONDS) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NotNull Disposable d) { + + } + + @Override + public void onNext(@NotNull Long aLong) { + + } + + @Override + public void onError(@NotNull Throwable e) { + + } + + @Override + public void onComplete() { + viewBinding.btnSelect.setClickable(true); + } + }); + } + + public void showSelectAll(Activity activity, View view, PopupWindow.OnDismissListener dismissListener, SelectReturnCallback selectReturnCallback) { + if (selectAddressPopupWindow == null) { + int i = getResources().getDisplayMetrics().heightPixels - DimensionConvert.dip2px(activity, 88) - DimensionConvert.dip2px(activity, 118); + selectAddressPopupWindow = new SelectAddressPopupWindow(activity, selectReturnCallback, LinearLayout.LayoutParams.MATCH_PARENT, + i); + } + //监听窗口的焦点事件,点击窗口外面则取消显示 + selectAddressPopupWindow.getContentView().setOnFocusChangeListener((v, hasFocus) -> { + if (!hasFocus) { + selectAddressPopupWindow.dismiss(); + } + }); + selectAddressPopupWindow.setOnDismissListener(dismissListener); + //popWindow消失监听方法 + WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); + lp.alpha = 0.7f; + activity.getWindow().setAttributes(lp); + //设置默认获取焦点 + selectAddressPopupWindow.setFocusable(true); + int xOffset = 10; + //以某个控件的x和y的偏移量位置开始显示窗口 + selectAddressPopupWindow.showAsDropDown(view, xOffset, 30); + //如果窗口存在,则更新 + selectAddressPopupWindow.update(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/AuthenticationActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/AuthenticationActivity.java new file mode 100644 index 0000000..420087c --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/AuthenticationActivity.java @@ -0,0 +1,408 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.telephony.TelephonyManager; +import android.util.Log; +import android.view.View; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.anhui.police.auth.AuthUser; +import com.anhui.police.auth.sdk.AuthConfig; +import com.anhui.police.auth.sdk.AuthSDK; +import com.anhui.police.auth.sdk.AuthType; +import com.anhui.police.auth.sdk.callback.IAuthTaskType; +import com.anhui.police.auth.sdk.callback.IAuthUserListener; + +import com.google.gson.JsonObject; + +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.BaseRecycleBtnClickListener; +import com.rs.macall.androidx.basemodel.callback.PermissionListener; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.utils.HandlerUtils; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; + +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityAuthenticationBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.AuthManageItem; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.util.ReadDeviceInfo; +import com.ycgis.macall.personalcenter.v.adapter.AuthManageAdapter; + +import org.jetbrains.annotations.NotNull; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import io.reactivex.Observable; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; + +/** + * 认证管理 + */ +public class AuthenticationActivity extends BaseViewBindActivity implements PermissionListener { + private AuthManageAdapter adapter; + + private Handler myHandler; + private String imei = "", imsi = ""; + private boolean isRefresh = false; + + private AuthType authType; + + @Override + protected ActivityAuthenticationBinding getViewBinding() { + return ActivityAuthenticationBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + viewBinding.rvAuthe.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); + SmartRefreshLayoutHelp.setPullDownToRefresh(getContext(), viewBinding.srlAuthe); + myHandler = HandlerUtils.getActivity(this); + AuthSDK.getDefault().getToken(0.8f, iAuth); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void start() { + viewBinding.authTitle.leftImage.setImageDrawable(getDrawables(R.drawable.back_cliener)); + viewBinding.authTitle.titleleft.setOnClickListener(v -> finish()); + viewBinding.authTitle.contentTitle.setText(R.string.authManage); + String[] needPermissions = {Manifest.permission.READ_PHONE_STATE, Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + requestPermissions(needPermissions, this); + } else { + initPage(); + } + } + + private void initPage() { + getImei(); + viewBinding.srlAuthe.setOnRefreshListener(refreshLayout -> getData()); + } + + private void getData() { + Map param = new HashMap<>(); + param.put("token", RuanseeApplication.getAppCache().getToken()); + param.put("clientType", "MOBILE"); + param.put("deviceFlags", imei); + param.put("imsi1", imsi); + param.put("sysCode", RuanseeApplication.getAppCache().getSysmCode()); + param.put("types", "1;2;3;4"); + ApiModel.requestIO(RetrofitService.getBaseInstance().getLoginType("http://20.90.2.2/UniAuth/api/sso/v1/verifyBind", param), new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + Log.e(TAG, msg); + HandlerUtils.sendHandlerMessage(myHandler, -245, msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + Log.w(TAG, result.toString()); + try { + JSONObject object = new JSONObject(result.toString()); + String code = TypConversion.getJsonStr(object, "code"); + if (!code.equals("200")) { + HandlerUtils.sendHandlerMessage(myHandler, -245, + TypConversion.strToInt(TypConversion.getJsonStr(object, "code")), 0, + TypConversion.getJsonStr(object, "content")); + return; + } + JSONObject object1 = object.getJSONObject("data"); + AuthManageItem item1 = new AuthManageItem("证书认证", + TypConversion.getJsonStr(object1, "1").endsWith("true"), false, AuthType.DIGITAL_CERTIFICATE); + item1.setActivate(false); + item1.setBaseType(1); + AuthManageItem item2 = new AuthManageItem("手势认证", + TypConversion.getJsonStr(object1, "2").endsWith("true"), true, AuthType.GESTURE); + item2.setActivate(true); + item2.setBaseType(1); + AuthManageItem item3 = new AuthManageItem("人像认证", + TypConversion.getJsonStr(object1, "3").endsWith("true"), false, AuthType.FACE); + item3.setActivate(true); + item3.setBaseType(1); + AuthManageItem item4 = new AuthManageItem("语音认证", + TypConversion.getJsonStr(object1, "4").endsWith("true"), false, AuthType.VOICE); + item4.setActivate(false); + item4.setBaseType(1); + AuthManageItem item5 = new AuthManageItem("用户名密码认证", + true, true, AuthType.PWD); + item5.setBaseType(1); + item5.setActivate(true); + item5.setType(2); + List datalist = new ArrayList<>(); + datalist.add(item5); + datalist.add(item1); + datalist.add(item2); + datalist.add(item3); + datalist.add(item4); + AuthType authType = RuanseeApplication.getAppCache().getAuthType(); + for (AuthManageItem item : datalist) { + if (item.getAuthType() == authType) { + item.setSelect(true); + HandlerUtils.sendHandlerMessage(myHandler, 1555, item.getName()); + } + } + HandlerUtils.sendHandlerMessage(myHandler, 152, datalist); + } catch (JSONException e) { + e.printStackTrace(); + HandlerUtils.sendHandlerMessage(myHandler, -245, "解析错误!"); + } + } + }); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case -245: + if (isRefresh) { + isRefresh = false; + viewBinding.srlAuthe.finishRefresh(); + } + if (msg.arg1 == 900) { + myHandler.sendEmptyMessageDelayed(2514, 800); + } + List list = new ArrayList<>(); + AuthManageItem item = new AuthManageItem("",false,false,null); + item.setBaseType(-1); + item.setBaseMessage((String) msg.obj); + list.add(item); + initData(list); + ToastUtil.centered(this, (String) msg.obj); + break; + case 152: + if (isRefresh) { + isRefresh = false; + viewBinding.srlAuthe.finishRefresh(); + } + initData((List) msg.obj); + break; + case 1555: + viewBinding.tvDqdlfs.setText((String) msg.obj); + break; + case 2514: +// EventBus.getDefault().post(new BackLogEvent(-401)); + RuanseeApplication.saveData("loginType", "true"); + Intent intent = new Intent(this, StartActivity.class); + startActivity(intent); + finish(); + break; + case 5894: +// System.exit(0); + +// List types = new ArrayList<>(); +// types.add(RuanseeApplication.getAppCache().getAuthType()); +// AuthConfig config = AuthConfig.builder(); +// config.setThemeColor(ContextCompat.getColor(getApplicationContext(), R.color.colorAccent)); +// config.setAuthMethodType(AuthConfig.AuthMethodType.AUTH_METHOD_DEFAULT); +// config.setAuthTypes(types); +//// AuthSDK.getDefault().getToken(); +// AuthSDK.init("55b161aefd464849b48986a1073d5622", this, config); +//// EventBus.getDefault().post(new BackLogEvent(-401)); +// intent = new Intent(this, StartActivity.class); +// RuanseeApplication.saveData("loginType", "true"); +// startActivity(intent); +// finish(); + break; + } + } + + + private IAuthUserListener iAuth = new IAuthUserListener() { + @Override + public void onAuthTaskCallback(@IAuthTaskType int authTaskType, int authCode, @Nullable @org.jetbrains.annotations.Nullable String authResult, + @Nullable @org.jetbrains.annotations.Nullable AuthUser authUser, @Nullable @org.jetbrains.annotations.Nullable String level) { + LogUtils.w(TAG, String.format("code:%s || authTaskType:%s || authResult:%s || level:%s", authCode, authTaskType, authResult, level)); + if (authCode == 200) { + RuanseeApplication.getAppCache().setToken(authResult); + viewBinding.srlAuthe.autoRefresh(); + } else { + ToastUtil.centered(getContext(), authResult); + if (authCode == 900 || "token失效".equals(authResult)) { + AuthSDK.getDefault().startAuth(this); + return; + } + ysFinish(); + } + } + }; + + private void ysFinish() { + Observable.timer(1500, TimeUnit.MILLISECONDS) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NotNull Disposable d) { + + } + + @Override + public void onNext(@NotNull Long aLong) { + finish(); + } + + @Override + public void onError(@NotNull Throwable e) { + + } + + @Override + public void onComplete() { + + } + }); + } + + //解绑 + private void startUnAuthBinding() { + if (authType == null) return; + AuthSDK.getDefault().startUnAuthBinding(RuanseeApplication.getAppCache().getToken(), + authType, iAuth); + } + + //绑定 + private void startAuthBinding() { + if (authType == null) return; + AuthSDK.getDefault().startAuthBinding( + RuanseeApplication.getAppCache().getToken(), + authType, iAuth); + } + + private void initData(List data) { + viewBinding.srlAuthe.finishRefresh(); + if (adapter == null) { + adapter = new AuthManageAdapter(this, data); + viewBinding.rvAuthe.setAdapter(adapter); + adapter.setBtnClickListener(new BaseRecycleBtnClickListener() { + @Override + public void onSingleClick(View v, int position, int what, Object msg) { + AuthManageItem item = adapter.getDataItem(position); + authType = item.getAuthType(); + if (item.getType() == 2) { + Intent intent = new Intent(AuthenticationActivity.this, UpdatePasswordActivity.class); + intent.putExtra("imei", imei); + intent.putExtra("imsi", imsi); + startActivity(intent); + return; + } + if (item.getAuthType() != null) { + if (item.isAutheType()) { // 先调登录 + List types = new ArrayList<>(); + types.add(authType); + AuthSDK sdk = AuthSDK.getDefault(); + AuthConfig config = AuthConfig.builder(); + config.setThemeColor(ContextCompat.getColor(getApplicationContext(), + R.color.colorPrimaryDark)); + config.setAuthMethodType(AuthConfig.AuthMethodType.AUTH_METHOD_DEFAULT); + config.setAuthTypes(types); + if (sdk == null) { + AuthSDK.init(RuanseeApplication.getAppCache().getSysmCode(), + AuthenticationActivity.this, config); + AuthSDK.getDefault().startAuth(iAuth); + } else { + sdk.startAuth(config, iAuth); + } + } else { + startAuthBinding(); + } + } + } + }); + adapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + AuthManageItem item = adapter.getDataItem(pointer); + if (!item.isActivate()) { + ToastUtil.centered(AuthenticationActivity.this, "暂不支持该方式登录!"); + return; + } + if (!item.isAutheType()){ + ToastUtil.centered(AuthenticationActivity.this,"请先设置该认证方式!"); + return; + } + List data = adapter.getData(); + for (AuthManageItem item1 : data) { + item1.setSelect(false); + } + item.setSelect(true); + RuanseeApplication.getAppCache().setAuthType(item.getAuthType()); + adapter.notifyDataSetChanged(); + viewBinding.tvDqdlfs.setText(item.getName()); + ApiModel.uploadOperationLog("3","3","用户切换登录方式"); + ToastUtil.centered(AuthenticationActivity.this, "登录方式切换成功,下次登录时将使用该模式登录!"); +// myHandler.sendEmptyMessageDelayed(5894, 500); + } + }); + + } else { + adapter.upData(data); + } + } + + @SuppressLint({"MissingPermission", "HardwareIds"}) + private void getImei() { + imei = RuanseeApplication.getAppCache().getImei(); + if (StringUtil.isNullOrEmpty(imei)) { + imei = ReadDeviceInfo.getDeviceId(getContext()); + if (StringUtil.isNullOrEmpty(imei)) { + imei = ReadDeviceInfo.getIMEI1(getContext()); + RuanseeApplication.getAppCache().setImei(imei); + } + } + imsi = RuanseeApplication.getAppCache().getImsi(); + if (StringUtil.isNullOrEmpty(imsi)) { + imsi = ReadDeviceInfo.getIMSI(getContext(), 0); + if (StringUtil.isNullOrEmpty(imsi)) { + imsi = ReadDeviceInfo.getIMSI(getContext(), 1); + } + RuanseeApplication.getAppCache().setImsi(imsi); + } + } + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + Log.e("auth", requestCode + "-->" + resultCode); + AuthSDK.getDefault().onActivityResult(requestCode, resultCode, data); + } + + @Override + public void onGranted() { + initPage(); + } + + @Override + public void onDenied(List deniDPermission) { + showMissingPermissionDialog(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/FrequentlyQuestionsActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/FrequentlyQuestionsActivity.java new file mode 100644 index 0000000..0092800 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/FrequentlyQuestionsActivity.java @@ -0,0 +1,132 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import android.os.Bundle; +import android.view.View; + +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityFrequentlyQuestionsBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.m.adapterbean.FrequentlyItemBean; +import com.ycgis.macall.personalcenter.m.requestbean.BaseRequestModel; +import com.ycgis.macall.personalcenter.m.requestbean.FrequentlyBean; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.v.adapter.FrequentlyQuestionsAdapter; +import com.ycgis.macall.personalcenter.v.fragment.FrequentlyQuestionsDetailsFragment; + +import java.util.ArrayList; +import java.util.List; + +/** + * 常见问题 + */ +public class FrequentlyQuestionsActivity extends BaseViewBindActivity { + private FrequentlyQuestionsAdapter adapter; + + @Override + protected ActivityFrequentlyQuestionsBinding getViewBinding() { + return ActivityFrequentlyQuestionsBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + viewBinding.frequentlyRvList.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); + SmartRefreshLayoutHelp.setPullDownToRefresh(getContext(), viewBinding.frequentlySrlRefresh); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void start() { + viewBinding.baseTitle.leftImage.setImageDrawable(getDrawables(R.drawable.back_cliener)); + viewBinding.baseTitle.contentTitle.setText(R.string.frequentlyQuestions); + viewBinding.baseTitle.titleleft.setOnClickListener(v -> finish()); + viewBinding.frequentlySrlRefresh.setOnRefreshListener(refreshLayout -> getFrequentlyData()); + viewBinding.frequentlySrlRefresh.autoRefresh(); + } + + private void getFrequentlyData() { + ApiModel.request(RetrofitService.getBaseInstance().getQuestion(), new BaseRequestCallback>>() { + @Override + public void onRequestFailure(String msg) { + List dataList = new ArrayList<>(); + BaseBean baseBean = new BaseBean() { + }; + baseBean.setBaseType(-1); + baseBean.setBaseMessage(msg); + dataList.add(baseBean); + initData(dataList); + } + + @Override + public void onRequestSuccess(BaseRequestModel> result) { + int code = result.getCode(); + List dataList = new ArrayList<>(); + if (code == 20041) { + List data = result.getData(); + for (FrequentlyBean bean : data) { + List data1 = bean.getData(); + bean.setBaseType(1); + dataList.add(bean); + for (int i = 0; i < data1.size(); i++) { + FrequentlyItemBean bean1 = data1.get(i); + bean1.setBaseType(2); + dataList.add(bean1); + } + dataList.get(dataList.size() - 1).setBaseType(3); + } + if (dataList.isEmpty()) { + BaseBean baseBean = new BaseBean() { + }; + baseBean.setBaseType(0); + baseBean.setBaseMessage("暂无数据"); + dataList.add(baseBean); + } + } else { + BaseBean baseBean = new BaseBean() { + }; + baseBean.setBaseType(-1); + baseBean.setBaseMessage(result.getMsg()); + dataList.add(baseBean); + } + initData(dataList); + } + }); + } + + private void initData(List baseBeans) { + if (adapter == null) { + adapter = new FrequentlyQuestionsAdapter(getContext(), baseBeans); + viewBinding.frequentlyRvList.setAdapter(adapter); + adapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + BaseBean dataItem = adapter.getDataItem(pointer); + if (dataItem.getBaseType() == 2 || dataItem.getBaseType() == 3) { + FrequentlyItemBean bean = (FrequentlyItemBean) dataItem; + FrequentlyQuestionsDetailsFragment.newInstance(bean).show(getSupportFragmentManager(), "WorkbenchManageFragment"); + } + } + }); + } else { + adapter.upData(baseBeans); + } + viewBinding.frequentlySrlRefresh.finishRefresh(); + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/MainActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/MainActivity.java new file mode 100644 index 0000000..4779d6b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/MainActivity.java @@ -0,0 +1,368 @@ +package com.ycgis.macall.personalcenter.v.activity; + + +import android.annotation.SuppressLint; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.job.JobInfo; +import android.app.job.JobScheduler; +import android.content.ComponentName; +import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.provider.Settings; +import android.util.DisplayMetrics; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.View; +import android.view.WindowManager; +import android.widget.LinearLayout; + +import androidx.annotation.Nullable; +import androidx.viewpager2.widget.ViewPager2; + +import com.anhui.police.market.callback.AbstractMarketResult; +import com.anhui.police.market.sdk.MarketConfigure; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.utils.DimensionConvert; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityMainBinding; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.request.CommonCompositeManage; +import com.ycgis.macall.personalcenter.p.rxjava.ResultObserver; +import com.ycgis.macall.personalcenter.p.service.GetMessageService; +import com.ycgis.macall.personalcenter.util.InsertAppUtils; +import com.ycgis.macall.personalcenter.util.NotificationUtils; +import com.ycgis.macall.personalcenter.v.adapter.MainFragmentAdapter; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import io.reactivex.Observable; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; + +import static android.app.Notification.EXTRA_CHANNEL_ID; +import static android.provider.Settings.EXTRA_APP_PACKAGE; + +public class MainActivity extends BaseViewBindActivity { + + + @Override + protected ActivityMainBinding getViewBinding() { + return ActivityMainBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { +// LinearLayoutManager manager = new LinearLayoutManager(getContext(),LinearLayoutManager.HORIZONTAL,false); + viewBinding.mainPageView.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL); + customClickListener = new CustomClickListener(300) { + @Override + public void onSingleClick(View v) { + bindViewClick(v); + } + }; + setViewOnClickListener(viewBinding.mainBtnBottom1); + setViewOnClickListener(viewBinding.mainBtnBottom2); + setViewOnClickListener(viewBinding.mainBtnBottom3); + setViewOnClickListener(viewBinding.mainBtnBottom4); + viewBinding.mainPageView.setOffscreenPageLimit(3); + //TODO 设置是否可滑动切换 + // viewBinding.mainPageView.setUserInputEnabled(false); + viewBinding.mainPageView.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { + + @Override + public void onPageSelected(int position) { + super.onPageSelected(position); + switchMainButton(viewBinding.mainPageView.getCurrentItem()); + } + }); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void start() { + viewBinding.mainPageView.setAdapter(new MainFragmentAdapter(this)); //判断应用有无通知权限 + boolean bc = NotificationUtils.isNotifyEnabled(this); + if (!bc) { + //无权限时应弹框提醒 + showNotificationDialog(); + } + startJobScheduler(); + //3.0.20240111 没有添加检测更新 + MarketConfigure.detectAppUpdates(this, false, "", new AbstractMarketResult() { + @Override + public void onResult(String result, boolean upgrade) { + LogUtils.w(result); + } + + @Override + public void onConfirm(int stateType) { + LogUtils.w("stateType:" + stateType); + + } + + @Override + public void onCancel() { + LogUtils.w("onCancel"); + } + + @Override + public void onWarning() { + LogUtils.w("onWarning"); + + } + + @Override + public void onResult(String result) { + LogUtils.w(result); + + } + }); +// installationDetectionComponents(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + CommonCompositeManage.getInstance().unDisposable("exitApp"); + } + +// //检测统一服务组件是否安装 +// private void installationDetectionComponents() { +// if (new InsertAppUtils().isInspectStaticFaceSDK(getContext())) { +// //没有安装统一服务组件 +// new AlertDialog.Builder(getContext()) +// .setTitle(R.string.kind_reminder) +// .setCancelable(false) +// .setMessage(R.string.not_insert_usc_apk) +// .setNegativeButton("不安装", new DialogInterface.OnClickListener() { +// @Override +// public void onClick(DialogInterface dialog, int which) { +// dialog.dismiss(); +// } +// }).setPositiveButton("去下载", new DialogInterface.OnClickListener() { +// @Override +// public void onClick(DialogInterface dialog, int which) { +// dialog.dismiss(); +// Intent intent = new Intent(Intent.ACTION_VIEW); +// intent.setData(Uri.parse("http://20.90.1.135/download/tyfwzj.apk")); +// startActivity(intent); +// } +// }).create().show(); +// } +// } + + @Override + protected void bindViewClick(View v) { + int num = 0; + if (v.getId() == R.id.main_btn_bottom1) { + num = 0; + } else if (v.getId() == R.id.main_btn_bottom2) { + num = 1; + } else if (v.getId() == R.id.main_btn_bottom3) { + num = 2; + } else if (v.getId() == R.id.main_btn_bottom4) { + num = 3; + } + viewBinding.mainPageView.setCurrentItem(num); + switchMainButton(num); + } + + private void showNotificationDialog() { + View view = getLayoutInflater().inflate(R.layout.dialog_remind, null, false); + Dialog dialog = new AlertDialog.Builder(getContext(), R.style.MyDialogTheme) + .setView(view) + .setCancelable(false) + .create(); + dialog.show(); + WindowManager.LayoutParams layoutParams = dialog.getWindow().getAttributes(); + DisplayMetrics dm = getResources().getDisplayMetrics(); + layoutParams.width = dm.widthPixels - DimensionConvert.dip2px(getContext(), 50); + layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.CENTER; + dialog.getWindow().setAttributes(layoutParams); + dialog.findViewById(R.id.btn_determine).setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + dialog.dismiss(); + setNotificationActivity(); + } + }); + } + + public void setNotificationActivity() { + Intent localIntent = new Intent(); + //直接跳转到应用通知设置的代码: + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//8.0及以上 + localIntent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS); + //这种方案适用于 API 26, 即8.0(含8.0)以上可以用 + localIntent.putExtra(EXTRA_APP_PACKAGE, getPackageName()); + localIntent.putExtra(EXTRA_CHANNEL_ID, getApplicationInfo().uid); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0以上到8.0以下 + //这种方案适用于 API21——25,即 5.0——7.1 之间的版本可以使用 + localIntent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS); + localIntent.putExtra("app_package", getPackageName()); + localIntent.putExtra("app_uid", getApplicationInfo().uid); + } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {//4.4 + localIntent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + localIntent.addCategory(Intent.CATEGORY_DEFAULT); + localIntent.setData(Uri.parse("package:" + getPackageName())); + } else { + //4.4以下没有从app跳转到应用通知设置页面的Action,可考虑跳转到应用详情页面, + localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + if (Build.VERSION.SDK_INT >= 9) { + localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); + localIntent.setData(Uri.fromParts("package", getPackageName(), null)); + } else if (Build.VERSION.SDK_INT <= 8) { + localIntent.setAction(Intent.ACTION_VIEW); + localIntent.setClassName("com.android.settings", "com.android.setting.InstalledAppDetails"); + localIntent.putExtra("com.android.settings.ApplicationPkgName", getPackageName()); + } + } + startActivityForResult(localIntent, 50); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == 50 && resultCode == 0) { + //判断应用有无通知权限 + boolean bc = NotificationUtils.isNotifyEnabled(this); + if (!bc) { + //无权限时应弹框提醒 + showNotificationDialog(); + } + } + } + + public void onSkipMyDetails(View view) { + startActivity(new Intent(getContext(), MyDetailsActivity.class)); + } + + public void onJumpMessage(View view) { + viewBinding.mainPageView.setCurrentItem(1); + switchMainButton(1); + } + + private void switchMainButton(int buttonNum) { + switch (buttonNum) { + case 0: + viewBinding.mainIvBottom1.setImageDrawable(getDrawables(R.drawable.icon_main_home)); + viewBinding.mainIvBottom2.setImageDrawable(getDrawables(R.drawable.icon_main_message_def)); + viewBinding.mainIvBottom3.setImageDrawable(getDrawables(R.drawable.icon_main_work_def)); + viewBinding.mainIvBottom4.setImageDrawable(getDrawables(R.drawable.icon_main_my_def)); + viewBinding.mainTvBottom1.setTextColor(getColors(R.color.blue)); + viewBinding.mainTvBottom2.setTextColor(getColors(R.color.colorGrey5)); + viewBinding.mainTvBottom3.setTextColor(getColors(R.color.colorGrey5)); + viewBinding.mainTvBottom4.setTextColor(getColors(R.color.colorGrey5)); + break; + case 1: + viewBinding.mainIvBottom1.setImageDrawable(getDrawables(R.drawable.icon_main_home_def)); + viewBinding.mainIvBottom2.setImageDrawable(getDrawables(R.drawable.icon_main_message)); + viewBinding.mainIvBottom3.setImageDrawable(getDrawables(R.drawable.icon_main_work_def)); + viewBinding.mainIvBottom4.setImageDrawable(getDrawables(R.drawable.icon_main_my_def)); + viewBinding.mainTvBottom1.setTextColor(getColors(R.color.colorGrey5)); + viewBinding.mainTvBottom2.setTextColor(getColors(R.color.blue)); + viewBinding.mainTvBottom3.setTextColor(getColors(R.color.colorGrey5)); + viewBinding.mainTvBottom4.setTextColor(getColors(R.color.colorGrey5)); + break; + case 2: + viewBinding.mainIvBottom1.setImageDrawable(getDrawables(R.drawable.icon_main_home_def)); + viewBinding.mainIvBottom2.setImageDrawable(getDrawables(R.drawable.icon_main_message_def)); + viewBinding.mainIvBottom3.setImageDrawable(getDrawables(R.drawable.icon_main_work)); + viewBinding.mainIvBottom4.setImageDrawable(getDrawables(R.drawable.icon_main_my_def)); + viewBinding.mainTvBottom1.setTextColor(getColors(R.color.colorGrey5)); + viewBinding.mainTvBottom2.setTextColor(getColors(R.color.colorGrey5)); + viewBinding.mainTvBottom3.setTextColor(getColors(R.color.blue)); + viewBinding.mainTvBottom4.setTextColor(getColors(R.color.colorGrey5)); + break; + case 3: + viewBinding.mainIvBottom1.setImageDrawable(getDrawables(R.drawable.icon_main_home_def)); + viewBinding.mainIvBottom2.setImageDrawable(getDrawables(R.drawable.icon_main_message_def)); + viewBinding.mainIvBottom3.setImageDrawable(getDrawables(R.drawable.icon_main_work_def)); + viewBinding.mainIvBottom4.setImageDrawable(getDrawables(R.drawable.icon_main_my)); + viewBinding.mainTvBottom1.setTextColor(getColors(R.color.colorGrey5)); + viewBinding.mainTvBottom2.setTextColor(getColors(R.color.colorGrey5)); + viewBinding.mainTvBottom3.setTextColor(getColors(R.color.colorGrey5)); + viewBinding.mainTvBottom4.setTextColor(getColors(R.color.blue)); + break; + } + } + + private boolean isExit = false; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (isExit) { + finish(); + return false; + } else { + isExit = true; + ToastUtil.centered(getContext(), "在按一次退出个人中心"); + modificationTime(); + return false; + } + } + return super.onKeyDown(keyCode, event); + } + + + @SuppressLint("NewApi") + public void startJobScheduler() { + JobScheduler jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE); + @SuppressLint("JobSchedulerService") JobInfo.Builder builder = new JobInfo.Builder(1, new ComponentName(this, GetMessageService.class)); + if (Build.VERSION.SDK_INT >= 24) { + builder.setMinimumLatency(RuanseeApplication.RefreshMessageTime); //执行的最小延迟时间 + builder.setOverrideDeadline(RuanseeApplication.RefreshMessageTime); //执行的最长延时时间 + builder.setBackoffCriteria(RuanseeApplication.RefreshMessageTime, JobInfo.BACKOFF_POLICY_LINEAR);//线性重试方案 + } else { + builder.setPeriodic(RuanseeApplication.RefreshMessageTime); + } + builder.setPersisted(true); // 设置设备重启时,执行该任务 + builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); + builder.setRequiresCharging(false);//设置是否在只有插入充电器的时候执行 + builder.setRequiresDeviceIdle(false);//设置手机系统处于空闲状态下执行 + JobInfo info = builder.build(); + jobScheduler.schedule(info); //开始定时执行该系统任务 + } + + private void modificationTime() { + Observable.timer(1000, TimeUnit.MILLISECONDS) + .subscribe(new ResultObserver("exitApp") { + @Override + protected void onSubscribe(String identifierKey, @NotNull Disposable d) { + CommonCompositeManage.getInstance().addDisposable(identifierKey,d); + } + + @Override + protected void onNext(String identifierKey, @NotNull Long data) { + CommonCompositeManage.getInstance().unDisposable(identifierKey); + isExit = false; + } + + @Override + protected void onComplete(String identifierKey) { + CommonCompositeManage.getInstance().unDisposable(identifierKey); + isExit = false; + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/MsgDetailsActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/MsgDetailsActivity.java new file mode 100644 index 0000000..c37093a --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/MsgDetailsActivity.java @@ -0,0 +1,99 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import android.os.Bundle; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityMsgDetailsBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.MessageBean; +import com.ycgis.macall.personalcenter.p.app.AppCache; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import io.reactivex.Observable; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; + + +public class MsgDetailsActivity extends BaseViewBindActivity { + private MessageBean msgData; + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected ActivityMsgDetailsBinding getViewBinding() { + return ActivityMsgDetailsBinding.inflate(getLayoutInflater()); + } + + @Override + protected void init() { + + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + msgData = (MessageBean) getIntent().getSerializableExtra("msgData"); + } + + @Override + protected void start() { + viewBinding.baseTitle.leftImage.setImageDrawable(getDrawables(R.drawable.ic_back)); + viewBinding.baseTitle.contentTitle.setText("消息详情"); + viewBinding.baseTitle.titleleft.setOnClickListener(v -> finish()); + if (msgData == null) { + ToastUtil.centered(getContext(), "接收参数错误!"); + ys(); + return; + } + viewBinding.msgTitle.setText(msgData.getTitle()); + viewBinding.msgContent.setText(msgData.getContent()); + viewBinding.msgDept.setText(msgData.getAppName()); + viewBinding.msgTime.setText(msgData.getTime()); + if (StringUtil.hasContent(msgData.getAppIcon())) { + String imgUrl = AppCache.BASE_IMAGE_URL + msgData.getAppIcon(); + //图片加载自己实现 + Glide.with(viewBinding.imageView10) + .load(imgUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) + .into(viewBinding.imageView10); + } + } + + private void ys() { + Observable.timer(1000, TimeUnit.MILLISECONDS) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NotNull Disposable d) { + + } + + @Override + public void onNext(@NotNull Long aLong) { + + } + + @Override + public void onError(@NotNull Throwable e) { + + } + + @Override + public void onComplete() { + finish(); + ; + } + }); + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/MyDetailsActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/MyDetailsActivity.java new file mode 100644 index 0000000..3183b61 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/MyDetailsActivity.java @@ -0,0 +1,479 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Build; +import android.os.Bundle; +import android.os.Message; +import android.provider.MediaStore; +import android.telephony.PhoneNumberUtils; +import android.telephony.TelephonyManager; +import android.text.InputType; +import android.util.Log; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.lifecycle.Observer; +import androidx.lifecycle.ViewModelProviders; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; + +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.callback.PermissionListener; +import com.rs.macall.androidx.basemodel.request.RequestCode; +import com.rs.macall.androidx.basemodel.utils.BitMapUtils; +import com.rs.macall.androidx.basemodel.utils.DimensionConvert; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityMyDetailsBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.app.UserData; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.callback.ImageCallBack; +import com.ycgis.macall.personalcenter.p.callback.UploadProgressListener; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.LoadPhotoImage; +import com.ycgis.macall.personalcenter.p.request.MediaTypeUtils; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.p.request.UploadProgressResponsBody; +import com.ycgis.macall.personalcenter.util.FileUtils; +import com.ycgis.macall.personalcenter.util.PhoneValidateUtils; +import com.ycgis.macall.personalcenter.util.ReadDeviceInfo; +import com.ycgis.macall.personalcenter.util.UriUtils; +import com.ycgis.macall.personalcenter.v.custom.InputDialog; +import com.ycgis.macall.personalcenter.v.viewmodel.MyDetailsViewModel; + +import org.json.JSONException; +import org.json.JSONObject; +import org.w3c.dom.Text; + +import java.io.File; +import java.util.List; + +import io.reactivex.observers.TestObserver; +import okhttp3.MultipartBody; +import okhttp3.RequestBody; +import top.zibin.luban.OnCompressListener; + +public class MyDetailsActivity extends BaseViewBindActivity implements PermissionListener { + private InputDialog inputDialog; + private TextView tvUpdate; + private MyDetailsViewModel viewModel; + private String imei = "", imsi = ""; + private File photoFile; + + private boolean isUpdate = false; + public static final int UPDATE_INFO = 3365; + + //检测组件 下载组件地址 ;http://20.90.1.135/download/tyfwzjV1.0.3.apk + private LoadPhotoImage loadPhotoImage; + + @Override + protected ActivityMyDetailsBinding getViewBinding() { + return ActivityMyDetailsBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + private void returnPreviousPage() { + if (isUpdate) { + setResult(UPDATE_INFO); + } + finish(); + } + + @Override + protected void init() { + viewModel = ViewModelProviders.of(this).get(MyDetailsViewModel.class); + //13.98 + 0.55 - 8 + //5000 1000 13.38 - 80000 5.38 + // 1300 + 3300 + 800 = 5400 + //9500 - 5400 = 4100 = 预留800 = 3300 + viewModel.addUpdateLiveDataObserve(this, new Observer() { + @Override + public void onChanged(BaseBean baseBean) { + baseDismissDialog(); + if (baseBean.getBaseType() == -1) { + ToastUtil.centered(getContext(), baseBean.getBaseMessage()); + return; + } + isUpdate = true; + if (baseBean.getBaseType() == 1) { + RuanseeApplication.getUserData().setPhone1(baseBean.getBaseMessage()); + viewBinding.myDetailsTvPhone1.setText(baseBean.getBaseMessage()); + } + if (baseBean.getBaseType() == 2) { + RuanseeApplication.getUserData().setPhone2(baseBean.getBaseMessage()); + viewBinding.myDetailsTvPhone2.setText(baseBean.getBaseMessage()); + } + } + }); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void start() { + viewBinding.myDetailsTitle.leftImage.setImageDrawable(getDrawables(R.drawable.back_cliener)); + viewBinding.myDetailsTitle.contentTitle.setText("个人信息"); + UserData userData = RuanseeApplication.getUserData(); + viewBinding.myDetailsTvCode.setText(userData.getUserCode()); + viewBinding.myDetailsTvDept.setText(userData.getDeptName()); + viewBinding.myDetailsTvName.setText(userData.getUserName()); + viewBinding.myDetailsTvIdcard.setText(userData.getIdCardNum()); + viewBinding.myDetailsTvPosition.setText(userData.getPolice_post()); + viewBinding.myDetailsTvPhone1.setText(userData.getPhone1()); + viewBinding.myDetailsTvPhone2.setText(userData.getPhone2()); + setViewOnClickListener(viewBinding.myDetailsIvPhoto); + setViewOnClickListener(viewBinding.myDetailsTvPhone1); + setViewOnClickListener(viewBinding.myDetailsTvPhone2); + setViewOnClickListener(viewBinding.myDetailsTvDept); + setViewOnClickListener(viewBinding.myDetailsTitle.titleleft); + String[] needPermissions = {Manifest.permission.READ_PHONE_STATE, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE}; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + requestPermissions(needPermissions, this); + } else { + getImei(); + getPhotoImage(); + } + } + + private void getPhotoImage() { + if (loadPhotoImage == null) { + loadPhotoImage = new LoadPhotoImage(); + } + Bitmap bitmap = loadPhotoImage.loadPhotoImage(RuanseeApplication.getUserData().getPhoto(), viewBinding.myDetailsIvPhoto, new ImageCallBack() { + @Override + public void imageLoad(ImageView imageView, Bitmap bitmap) { + if (getActivity().isDestroyed())return; + Glide.with(getContext()) + .load(bitmap) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) + .into(viewBinding.myDetailsIvPhoto); + } + + @Override + public void imageLoadError(ImageView imageView, String message) { +// ToastUtil.centered(getContext(),message); + viewBinding.myDetailsIvPhoto.setImageDrawable(getDrawables(RuanseeApplication.getUserData().getErrorPhotoByIdCardNum())); + } + }); + + if (bitmap != null) { + Glide.with(getContext()) + .load(bitmap) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) + .into(viewBinding.myDetailsIvPhoto); + } + } + + + @SuppressLint({"MissingPermission", "HardwareIds"}) + private void getImei() { + imei = RuanseeApplication.getAppCache().getImei(); + if (StringUtil.isNullOrEmpty(imei)) { + imei = ReadDeviceInfo.getDeviceId(getContext()); + if (StringUtil.isNullOrEmpty(imei)) { + imei = ReadDeviceInfo.getIMEI1(getContext()); + } + RuanseeApplication.getAppCache().setImei(imei); + } + imsi = RuanseeApplication.getAppCache().getImsi(); + if (StringUtil.isNullOrEmpty(imsi)) { + imsi = ReadDeviceInfo.getIMSI(getContext(), 0); + if (StringUtil.isNullOrEmpty(imsi)) { + imsi = ReadDeviceInfo.getIMSI(getContext(), 1); + } + RuanseeApplication.getAppCache().setImsi(imsi); + } + } + @Override + protected void bindViewClick(View v) { + if (v.getId() == R.id.titleleft) { + returnPreviousPage(); + } else if (v.getId() == R.id.my_details_iv_photo) { + updatePhotoDialog("选择头像"); + } else if (v.getId() == R.id.my_details_tv_dept) { + ToastUtil.centered(getContext(), "正在紧急对接中"); +// Intent intent = new Intent(getContext(), UpdateDeptActivity.class); +// intent.putExtra("imei", imei); +// intent.putExtra("imsi", imsi); +// startActivity(intent); + } else if (v.getId() == R.id.my_details_tv_phone1) { + upDate(1, "修改移动警务号码", viewBinding.myDetailsTvPhone1); + } else if (v.getId() == R.id.my_details_tv_phone2) { + upDate(2, "修改手机号码", viewBinding.myDetailsTvPhone2); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (resultCode == Activity.RESULT_OK) { + if (requestCode == RequestCode.REQUEST_PHOTO) { //现场照片回调 + processingPictures(true); + return; + } + if (requestCode == RequestCode.REQUEST_PHOTO_ALBUM) { + if (data == null) { + ToastUtil.centered(this, "选择照片失败!"); + return; + } + String ss = UriUtils.getRealPathFromUri(this, data.getData()); + photoFile = new File(ss); + if (photoFile.length() > 307200) { + processingPictures(false); + return; + } + uploadPhoto(); + } + } + super.onActivityResult(requestCode, resultCode, data); + } + + /** + * 压缩图片 + * + * @param isDel 是否删除原图片 + */ + private void processingPictures(final boolean isDel) { + if (photoFile != null) { + BitMapUtils.lubanCompress(getContext(), photoFile, FileUtils.IMAGE_DIR, new OnCompressListener() { + @Override + public void onStart() { + + } + + @Override + public void onSuccess(File file) { + if (isDel) { + if (photoFile != null || !photoFile.getName().equals(file.getName())) { + photoFile.delete(); + photoFile = null; + } + } + int pp = FileUtils.readPictureDegree(file.getAbsolutePath()); + if (pp != 0) { + Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); + bitmap = FileUtils.rotateImage(pp, bitmap); + photoFile = BitMapUtils.saveBitmap(FileUtils.IMAGE_DIR, file.getName(), bitmap); + } else { + photoFile = file; + } + uploadPhoto(); + } + + @Override + public void onError(Throwable e) { + photoFile.delete(); + photoFile = null; + ToastUtil.centered(getContext(), e.getMessage()); +// Message message = myHandler.obtainMessage(-500, "图片压缩失败,请重新拍摄!"); +// myHandler.sendMessage(message); + } + }); + } + } + + + /** + * 头像选择框 + * + * @param title 提示信息 + */ + private void updatePhotoDialog(String title) { + View view = LayoutInflater.from(this).inflate(R.layout.dialog_select_photo, null, false); + final Dialog dialog = new AlertDialog.Builder(this, R.style.MyDialogTheme) + .setView(view) + .create(); + Window dialogWindow = dialog.getWindow(); + // 设置 dialog 显示的位置 + dialogWindow.setGravity(Gravity.BOTTOM); + int ss = DimensionConvert.dip2px(this, 10); + // 设置 dialog 的边距 + dialogWindow.getDecorView().setPadding(ss, 0, ss, ss); + // 设置 标题 + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + // 获取 LayoutParams + WindowManager.LayoutParams lp = dialogWindow.getAttributes(); + // 设置 dialog 宽度高度 + lp.width = WindowManager.LayoutParams.MATCH_PARENT; + lp.height = WindowManager.LayoutParams.WRAP_CONTENT; + dialogWindow.setAttributes(lp); + dialog.show(); + TextView tv = dialog.findViewById(R.id.tv_dialog_title); + tv.setText(title); + //相机 + view.findViewById(R.id.btn_camera).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // 拍照 + photoFile = new File(FileUtils.IMAGE_DIR, FileUtils.getPhotoName()); + Intent intent = UriUtils.getPhotoIntent(getContext(), photoFile); + startActivityForResult(intent, RequestCode.REQUEST_PHOTO); + dialog.dismiss(); + } + }); + //相册 + view.findViewById(R.id.btn_album).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + openSysAlbum(); + dialog.dismiss(); + } + }); + + } + + /** + * 打开系统相册 + */ + private void openSysAlbum() { + Intent albumIntent = new Intent(Intent.ACTION_PICK); + albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); + startActivityForResult(albumIntent, RequestCode.REQUEST_PHOTO_ALBUM); + } + + private void upDate(int mun, String title, TextView tv) { + if (inputDialog == null) { + inputDialog = new InputDialog(getContext()); + } + inputDialog.show(); + inputDialog.setInputTitle(title); + String textString = getTextString(tv); + String s = "暂无".equals(textString) ? "" : textString; + inputDialog.setInputEdit(s); + inputDialog.setInputType(InputType.TYPE_CLASS_PHONE); + inputDialog.setSubmitListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + String inputEditText = inputDialog.getInputEditText(); + if (StringUtil.isNullOrEmpty(inputEditText)) { + ToastUtil.centered(getContext(), "请输入内容!"); + return; + } + if (!PhoneValidateUtils.isLegitimatePhoneNum(inputEditText)) { + ToastUtil.centered(getContext(), "请输入正确的电话号码!"); + return; + } + inputDialog.dismiss(); + baseShowDialog("正在提交请稍后..."); + viewModel.sendUpdate(mun, inputDialog.getInputEditText(), imsi, imei); + } + }); + inputDialog.create(); + } + + /** + * 上传用户头像 + */ + public void uploadPhoto() { + String fileName = photoFile.getName(); + RequestBody requestBody = new MultipartBody.Builder() + .setType(MultipartBody.FORM) + .addFormDataPart("token", RuanseeApplication.getAppCache().getToken()) + .addFormDataPart("clientType", "MOBILE") + .addFormDataPart("imsi1", imsi) + .addFormDataPart("deviceFlags", imei) + .addFormDataPart("sysCode", RuanseeApplication.getAppCache().getSysmCode()) + .addFormDataPart("file", fileName, + UploadProgressResponsBody.createCustomRequestBody(MediaTypeUtils.getMediaType(fileName), photoFile, new UploadProgressListener() { + @Override + public void onUploadProgress(long totalBytes, long remainingBytes, boolean done) { + LogUtils.w(TAG, "上传中 ========== 总长度:" + totalBytes + " == 当前进度:" + remainingBytes); + } + + @Override + public void onUploadDone(long totalSize) { + LogUtils.w(TAG, "上传完成========== 总长度:" + totalSize); + } + })).build(); + baseShowDialog("正在上传,请稍后..."); + //20.90.2.2/UniAuth/ + ApiModel.request(RetrofitService.getBaseInstance().saveAppOperationLog("http://20.90.2.2/UniAuth/api/sso/v1/uploadPhoto", requestBody), + new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + baseDismissDialog(); + ToastUtil.centered(getContext(), msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + baseDismissDialog(); + ApiModel.uploadOperationLog("3","3","用户修改统一用户头像"); + try { + JSONObject object = new JSONObject(result.toString()); + String code = TypConversion.getJsonStr(object, "code"); + if (!code.equals("200")) { + ToastUtil.centered(getContext(), TypConversion.getJsonStr(object, "content")); + return; + } + String data = TypConversion.getJsonStr(object, "data"); + JSONObject object1 = new JSONObject(data); + String id = TypConversion.getJsonStr(object1, "id"); + RuanseeApplication.getUserData().setPhoto(id); + if (photoFile != null) { + photoFile.delete(); + } + isUpdate = true; + getPhotoImage(); + } catch (JSONException e) { + e.printStackTrace(); + ToastUtil.centered(getContext(), e.getMessage()); + } + } + }); +// BaseRequest.uploadFile("http://20.90.1.126:7321/api/sso/v1/uploadPhoto", requestBody, myHandler); + } + + + @Override + public void onGranted() { + getImei(); + getPhotoImage(); + } + + @Override + public void onDenied(List deniDPermission) { + showMissingPermissionDialog(); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + returnPreviousPage(); + } + return super.onKeyDown(keyCode, event); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/MySuggestionsListActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/MySuggestionsListActivity.java new file mode 100644 index 0000000..d7ee007 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/MySuggestionsListActivity.java @@ -0,0 +1,172 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.viewbinding.ViewBinding; + +import android.content.Intent; +import android.os.Bundle; +import android.view.View; + +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityMySuggestionsListBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.FeedbackBean; +import com.ycgis.macall.personalcenter.m.requestbean.BaseRequestModel; +import com.ycgis.macall.personalcenter.m.requestbean.PagingModel; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.v.adapter.FeedBackListAdapter; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * 我的意见建议 + */ +public class MySuggestionsListActivity extends BaseViewBindActivity { + private int total, page, pageSize = 20; + private FeedBackListAdapter adapter; + + @Override + protected ActivityMySuggestionsListBinding getViewBinding() { + return ActivityMySuggestionsListBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + SmartRefreshLayoutHelp.setRefreshAndLoad(getContext(), viewBinding.suggestionsRslRefresh); + viewBinding.suggestionsRvList.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); + viewBinding.suggestionsRslRefresh.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull @NotNull RefreshLayout refreshLayout) { + + } + + @Override + public void onRefresh(@NonNull @NotNull RefreshLayout refreshLayout) { + viewBinding.suggestionsRslRefresh.resetNoMoreData(); + page = 1; + getData(); + } + }); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void start() { + viewBinding.suggestionsTitle.contentTitle.setText("我的反馈"); + viewBinding.suggestionsTitle.leftImage.setImageDrawable(getDrawable(R.drawable.back_cliener)); + viewBinding.suggestionsTitle.titleleft.setOnClickListener(V -> finish()); + viewBinding.suggestionsRslRefresh.autoRefresh(); + } + + private FeedbackBean getErrorBean(int type, String msg) { + FeedbackBean bean = new FeedbackBean(); + bean.setBaseType(type); + bean.setBaseMessage(msg); + return bean; + } + + private void getData() { + ApiModel.request("getMyFeedback", RetrofitService.getBaseInstance().feedbackList(page, pageSize), + new BaseRequestCallback>>() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(TAG, msg); + if (viewBinding.suggestionsRslRefresh.isRefreshing()){ + handRefreshData(null,-1,msg); + } + if (viewBinding.suggestionsRslRefresh.isLoading()){ + handLoadMoreData(null); + } + ToastUtil.centered(getContext(),msg); + } + + @Override + public void onRequestSuccess(BaseRequestModel> result) { + LogUtils.w(TAG, result.toString()); + if (result.getCode() == 20041) { + PagingModel data = result.getData(); + total = data.getCounts(); + List items = data.getItems(); + if (viewBinding.suggestionsRslRefresh.isRefreshing()){ + handRefreshData(items,0,"暂无反馈"); + } + if (viewBinding.suggestionsRslRefresh.isLoading()){ + handLoadMoreData(items); + } + if (page*pageSize>=total){ + viewBinding.suggestionsRslRefresh.finishLoadMoreWithNoMoreData(); + } + }else { + if (viewBinding.suggestionsRslRefresh.isRefreshing()){ + handRefreshData(null,-1,result.getMsg()); + } + if (viewBinding.suggestionsRslRefresh.isLoading()){ + handLoadMoreData(null); + } + ToastUtil.centered(getContext(),result.getMsg()); + } + } + }); + } + + private void initData(List items) { + if (adapter == null){ + adapter = new FeedBackListAdapter(getContext(),items); + viewBinding.suggestionsRvList.setAdapter(adapter); + adapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + if (adapter.getItemViewType(pointer)!=1)return; + Intent intent = new Intent(getContext(),SuggestionsDetailsActivity.class); + intent.putExtra("dataModel",adapter.getDataItem(pointer)); + startActivity(intent); + } + }); + }else { + adapter.upData(items); + } + } + + private void handRefreshData(List items,int type,String msg) { + if (items == null || items.isEmpty()) { + items = new ArrayList<>(); + items.add(getErrorBean(0, "暂无反馈")); + }else { + for (FeedbackBean b : items) { + b.setBaseType(1); + } + } + viewBinding.suggestionsRslRefresh.finishRefresh(); + initData(items); + } + + private void handLoadMoreData(List items) { + viewBinding.suggestionsRslRefresh.finishLoadMore(); + if (items!=null&&!items.isEmpty()){ + adapter.addData(items); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/OpenAppActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/OpenAppActivity.java new file mode 100644 index 0000000..5febf92 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/OpenAppActivity.java @@ -0,0 +1,834 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.location.Location; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.JavascriptInterface; +import android.webkit.WebSettings; +import android.widget.LinearLayout; + +import androidx.lifecycle.Lifecycle; + +import com.google.gson.Gson; +import com.just.agentweb.AgentWeb; +import com.just.agentweb.AgentWebConfig; +import com.just.agentweb.DefaultWebClient; +import com.king.zxing.CameraScan; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.callback.PermissionListener; +import com.rs.macall.androidx.basemodel.utils.HandlerUtils; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StatusBarUtil; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ruansee.macall.unifyservemodulesdk.ErrorMsg; +import com.ruansee.macall.unifyservemodulesdk.USMComponentSDK; +import com.ruansee.macall.unifyservemodulesdk.USMConfigure; +import com.ruansee.macall.unifyservemodulesdk.USMListener; +import com.ruansee.macall.unifyservemodulesdk.bean.CarOcrDataBean; +import com.ruansee.macall.unifyservemodulesdk.bean.ComponentBaseBean; +import com.ruansee.macall.unifyservemodulesdk.bean.FaceIdentifyBean; +import com.ruansee.macall.unifyservemodulesdk.bean.NFCBean; +import com.ruansee.macall.unifyservemodulesdk.bean.OcrSfzBean; +import com.ycgis.macall.personalcenter.BuildConfig; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityOpenAppBinding; +import com.ycgis.macall.personalcenter.m.model.SelectFileOptions; +import com.ycgis.macall.personalcenter.p.app.CrashHandler; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.app.UserData; +import com.ycgis.macall.personalcenter.p.callback.GPSLocationListener; +import com.ycgis.macall.personalcenter.p.callback.WebActivityCallback; +import com.ycgis.macall.personalcenter.p.presenter.WebViewPresenter; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.DownloadUtil; +import com.ycgis.macall.personalcenter.util.FileUtils; +import com.ycgis.macall.personalcenter.util.JiaMi; +import com.ycgis.macall.personalcenter.util.LocationGPSManage; + + +import java.io.File; +import java.net.URLDecoder; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OpenAppActivity extends BaseViewBindActivity implements PermissionListener { + private WebViewPresenter webViewPresenter; + /*统一服务组件SDK*/ + private USMComponentSDK usComponentSDK; + private AndroidMethodInterface androidMethodInterface; + private Handler myHandler; + private GPSLocationListener gpsLocationListener; + + ///////////////// 接收参数的KEY ////////////////// + /*第三方应用appId*/ + public static final String paramKey9 = "appName"; + /*第三方应用appId*/ + public static final String paramKey1 = "APPId"; + /*第三方应用的秘钥 */ + public static final String paramKey2 = "secret"; + /*第三方应用的链接地址*/ + public static final String paramKey3 = "LinkUrl"; + /*第三方应用对应的消息ID*/ + public static final String paramKey4 = "msgId"; + /*第三方应用对应的消息类型:当有的应用有多个消息类型时根据此参数判断*/ + public static final String paramKey5 = "msgType"; + /*第三方应用的操作类型 默认为 :login ,查看消息为: readMessage 查看搜索内容为:search */ + public static final String paramKey6 = "operationType"; + /*搜索类型 car / person*/ + public static final String paramKey7 = "searchType"; + /*搜索得到的数据Json 格式 */ + public static final String paramKey8 = "searchJson"; + /*搜 联系人 */ + public static final String paramKey10 = "ywry"; + /*联系人电话 */ + public static final String paramKey11 = "ywrylxdh"; + + ///////////////// 接收参数的KEY ////////////////// + + private AgentWeb mAgentWeb; + private String appID; + private String secret, appName; + private String msgId, msgType, operationType; + private String searchType, searchJson; + private String intoUrl = "http://20.90.1.150:8888/"; + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected ActivityOpenAppBinding getViewBinding() { + return ActivityOpenAppBinding.inflate(getLayoutInflater()); + } + + @Override + protected void init() { + Log.w(TAG, "init"); + webViewPresenter = new WebViewPresenter(getContext(), new WebActivityCallback() { + @Override + public void onShowOperationSelectDialog(String[] split, int whit) { + webViewPresenter.onShowOperationSelectDialog(getActivity(), whit, split); + } + + @Override + public void onFinish() { + finish(); + } + }); + //统一服务组件 +// USMConfigure.getDefault().init("16854", "stegst"); +// viewBinding.tvTestJs.setOnClickListener(new CustomClickListener() { +// @Override +// public void onSingleClick(View v) { +// mAgentWeb.getJsAccessEntrace().quickCallJs("callErrorResult", operationType, "test", "aseg"); +// } +// }); + androidMethodInterface = new AndroidMethodInterface(); + viewBinding.titleleft.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + androidMethodInterface.onBack(); + } + }); + viewBinding.titleright.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + androidMethodInterface.exitToHome(); + } + }); + viewBinding.btnRefresh.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + androidMethodInterface.reloadPage(); + } + }); + myHandler = HandlerUtils.getActivity(this); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + Log.w(TAG, "readInstanceState"); + if (savedInstanceState == null) { + appID = getIntent().getStringExtra(paramKey1); + secret = getIntent().getStringExtra(paramKey2); + intoUrl = getIntent().getStringExtra(paramKey3); + msgId = getIntent().getStringExtra(paramKey4); + msgType = getIntent().getStringExtra(paramKey5); + operationType = getIntent().getStringExtra(paramKey6); + appName = getIntent().getStringExtra(paramKey9); + searchType = getIntent().getStringExtra(paramKey7); + searchJson = getIntent().getStringExtra(paramKey8); + webViewPresenter.ywryName = getIntent().getStringExtra(paramKey10); + webViewPresenter.ywryPhone = getIntent().getStringExtra(paramKey11); + savePageCacheData(paramKey1, appID); + savePageCacheData(paramKey2, secret); + savePageCacheData(paramKey3, intoUrl); + savePageCacheData(paramKey4, msgId); + savePageCacheData(paramKey5, msgType); + savePageCacheData(paramKey6, operationType); + savePageCacheData(paramKey7, searchType); + savePageCacheData(paramKey8, searchJson); + savePageCacheData(paramKey9, appName); + savePageCacheData(paramKey10, webViewPresenter.ywryName); + savePageCacheData(paramKey11, webViewPresenter.ywryPhone); + } else { + appID = savedInstanceState.getString(paramKey1); + secret = savedInstanceState.getString(paramKey2); + intoUrl = savedInstanceState.getString(paramKey3); + msgId = savedInstanceState.getString(paramKey4); + msgType = savedInstanceState.getString(paramKey5); + operationType = savedInstanceState.getString(paramKey6); + appName = savedInstanceState.getString(paramKey9); + searchType = savedInstanceState.getString(paramKey7); + searchJson = savedInstanceState.getString(paramKey8); + webViewPresenter.ywryName = savedInstanceState.getString(paramKey10); + webViewPresenter.ywryPhone = savedInstanceState.getString(paramKey11); + } + usComponentSDK = USMConfigure.getDefault().getUsmComponentSDK(appID, secret); + viewBinding.contentTitle.setText(appName); + handInit(); + } + + @Override + protected void start() { + Log.w(TAG, "start"); +// initService(); + initWebView(); + usComponentSDK.setUSMListener(uscListener); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + requestPermissions(needPermissions, this); + } else { + initData(); + } + } + + private void initData() { + FileUtils.initFilePath(getContext()); + createFileDir(FileUtils.FILE_DIR); + createFileDir(FileUtils.DB_DIR); + createFileDir(FileUtils.DOWNLOADS_DIR); + createFileDir(FileUtils.IMAGE_DIR); + createFileDir(FileUtils.VOID_DIR); + createFileDir(FileUtils.LOG_DIR); + Log.w("Log目录", FileUtils.LOG_DIR); + CrashHandler.getInstance().init(getApplication(), FileUtils.LOG_DIR); + + String url = getUrl(); + LogUtils.d(TAG, url); +// mAgentWeb.getUrlLoader().loadUrl("file:///android_asset/TestJs.html"); + mAgentWeb.getUrlLoader().loadUrl(url); + ApiModel.uploadOperationLog("3", "3", "用户打开H5应用:" + appName); + } + + @Override + public void handleMessage(Message msg) { + if (msg.what == -55) {//刷新頁面 + if (!isDestroyed() && mAgentWeb != null) { + mAgentWeb.getWebCreator().getWebView().reload(); + } + } + } + + @Override + protected void onPause() { + if (mAgentWeb.getWebCreator() != null) { + mAgentWeb.getWebLifeCycle().onPause(); + } + super.onPause(); + } + + @Override + protected void onResume() { + if (mAgentWeb.getWebCreator() != null) { + mAgentWeb.getWebLifeCycle().onResume(); + } + super.onResume(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + Log.w(TAG, "onDestroy"); + AgentWebConfig.clearDiskCache(this.getContext()); + LocationGPSManage.getInstance().stopLocation(); + if (mAgentWeb.getWebCreator() != null) { + mAgentWeb.getWebLifeCycle().onDestroy(); + } + androidMethodInterface = null; + appID = ""; + secret = ""; +// if (mConn != null) { +// unbindService(mConn); +// } + } + + /** + * 绑定远程服务RemoteService + */ +// private void initService() { +// Log.w(TAG, "initService"); +// Intent intent = new Intent(getContext(), RemoteService.class); +//// intent.setComponent(new ComponentName("com.hongri.webview", "com.hongri.webview.service.RemoteService")); +// bindService(intent, mConn, BIND_AUTO_CREATE); +// } +// +// private final ServiceConnection mConn = new ServiceConnection() { +// @Override +// public void onServiceConnected(ComponentName name, IBinder service) { +//// Log.w(TAG, "onServiceConnected"); +// //当Service绑定成功时,通过Binder获取到远程服务代理 +// calculateInterface = CalculateInterface.Stub.asInterface(service); +// +// String url = getUrl(); +// LogUtils.d(TAG, url); +//// mAgentWeb.getUrlLoader().loadUrl("file:///android_asset/TestJs.html"); +// mAgentWeb.getUrlLoader().loadUrl(url); +// } +// +// @Override +// public void onServiceDisconnected(ComponentName name) { +//// Log.d(TAG, "onServiceDisconnected"); +// calculateInterface = null; +// } +// }; + private void createFileDir(String fileDirName) { + File file = new File(fileDirName); + if (file.exists()) return; + file.mkdirs(); + } + + private void handInit() { + if (StringUtil.isNullOrEmpty(operationType)) { + operationType = "login"; + } + if (StringUtil.isNullOrEmpty(intoUrl)) { + intoUrl = "https://www.baidu.com/my/index"; + } + webViewPresenter.intoUrl = intoUrl; + } + + private String getUrl() { + StringBuilder builder = new StringBuilder(); + builder.append(intoUrl); + if (intoUrl.contains("?")) { + builder.append("&userInfo="); + } else { + builder.append("?userInfo="); + } + String userInfo = new AndroidMethodInterface().getUserInfo(); +// try { +// String decrypt1 = JiaMi.decrypt(userInfo, appID, secret); +// LogUtils.w("解密", decrypt1); +// } catch (Exception e) { +// e.printStackTrace(); +// } + builder.append(userInfo); + if (operationType.equals("readMessage")) { + if (StringUtil.hasContent(msgId)) { + builder.append("&operation_type=readMessage"); + builder.append("&msg_id="); + builder.append(msgId); + if (StringUtil.hasContent(msgType)) { + builder.append("&msg_type="); + builder.append(msgType); + } + } else { + builder.append("&operation_type=login"); + } + } else if (operationType.equals("search")) { + builder.append("&search_type="); + builder.append(searchType); + builder.append("&operation_type=search"); + } else { + builder.append("&operation_type=login"); + } + return builder.toString(); + } + + @SuppressLint("SetJavaScriptEnabled") + private void initWebView() { + mAgentWeb = AgentWeb.with(getActivity()) + .setAgentWebParent(viewBinding.viewGroup, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)) + .useDefaultIndicator() + .setWebViewClient(webViewPresenter.mWebViewClient) + .setWebChromeClient(webViewPresenter.mWebChromeClient) + .setSecurityType(AgentWeb.SecurityType.STRICT_CHECK) + .setOpenOtherPageWays(DefaultWebClient.OpenOtherPageWays.DISALLOW)//打开其他应用时,弹窗咨询用户是否前往其他应用 + .addJavascriptInterface(androidMethodInterface.toName(), androidMethodInterface) + .createAgentWeb() + .ready().get(); + WebSettings webSettings = mAgentWeb.getAgentWebSettings().getWebSettings(); + webSettings.setJavaScriptEnabled(true); + webSettings.setDomStorageEnabled(true); +// webSettings.setLoadWithOverviewMode(true); +// webSettings.setLoadsImagesAutomatically(true); + webSettings.setBlockNetworkImage(false); +// webSettings.setJavaScriptCanOpenWindowsAutomatically(true); + webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); + + // 设置支持本地存储 +// webSettings.setDatabaseEnabled(true); +// //设置存储模式 +// webSettings.setCacheMode(WebSettings.LOAD_DEFAULT); +// webSettings.setAppCacheEnabled(true); + + + mAgentWeb.getWebCreator().getWebView().setHorizontalScrollBarEnabled(false); + if (BuildConfig.DEBUG) { + mAgentWeb.getWebCreator().getWebView().setWebContentsDebuggingEnabled(true); + } + + mAgentWeb.getWebCreator().getWebView().setDownloadListener((url1, userAgent, contentDisposition, mimetype, contentLength) -> { + if (StringUtil.isNullOrEmpty(url1)) { + ToastUtil.centered(getContext(), "下载链接为空,请检查链接是否真实!"); + return; + } + String s1 = url1.toLowerCase(); + if (!s1.startsWith("http://") && !s1.startsWith("https://")) { + ToastUtil.centered(getContext(), "URL缺少请求头,将默认使用Http协议下载"); + url1 = "http://" + url1; + } + + String fileName = ""; + if (StringUtil.hasContent(contentDisposition)) { + String[] split = contentDisposition.split("="); + fileName = split[split.length - 1]; + } + if (StringUtil.isNullOrEmpty(fileName)) { + fileName = url1.substring(url1.lastIndexOf("/") + 1); + + } + String jm = URLDecoder.decode(fileName); + if (fileName.length() > jm.length()) { + fileName = jm; + } + fileName = fileName.replace("/", "_").replace("\\", "_"); + + String s = FileUtils.DOWNLOADS_DIR + fileName; + File file = new File(s); + //打开文件 + if (file.exists()) + FileUtils.openFileByPath(getActivity(), file.getAbsolutePath()); + else { + baseShowDialog(String.format("正在下载'%s',请稍后...", fileName)); + webViewPresenter.downloadFile(url1, fileName, new DownloadUtil.OnDownloadListener() { + @Override + public void onDownloadSuccess(File file) { + baseDismissDialog(); + if (file.exists()) { + //打开文件 + ToastUtil.centered(getContext(), "文件下载成功!"); + FileUtils.openFileByPath(getActivity(), file.getAbsolutePath()); + } else { + ToastUtil.centered(getContext(), "文件下载失败!"); + } + } + + @Override + public void onDownloading(int progress) { + + } + + @Override + public void onDownloadFailed(String msg) { + baseDismissDialog(); + ToastUtil.centered(getContext(), "文件下载失败:" + msg); + } + }); + } + }); + } + + + private USMListener uscListener = new USMListener() { + @Override + public void onUSCSuccess(String operationType, ComponentBaseBean resultBean) { + LogUtils.d(TAG, operationType); + if (resultBean == null) { + ToastUtil.centered(getContext(), "错误的返回值!"); + mAgentWeb.getJsAccessEntrace().quickCallJs("callErrorResult", operationType, String.valueOf(ErrorMsg.ERROR_RESULT.getIndex()), ErrorMsg.ERROR_RESULT.getName()); + return; + } + if (resultBean instanceof NFCBean) { + NFCBean bean = (NFCBean) resultBean; + ToastUtil.centered(getContext(), "NFC返回:" + bean.getName()); + mAgentWeb.getJsAccessEntrace().quickCallJs("callNFCResult", new Gson().toJson(bean)); + return; + } + if (resultBean instanceof FaceIdentifyBean) { + FaceIdentifyBean bean = (FaceIdentifyBean) resultBean; + ToastUtil.centered(getContext(), "人像:" + bean.getName()); + mAgentWeb.getJsAccessEntrace().quickCallJs("callFaceIdentifyResult", new Gson().toJson(bean)); + return; + } + if (resultBean instanceof OcrSfzBean) { + OcrSfzBean bean = (OcrSfzBean) resultBean; + ToastUtil.centered(getContext(), "OCR身份证返回:" + bean.getName()); + mAgentWeb.getJsAccessEntrace().quickCallJs("callCORSfzResult", new Gson().toJson(bean)); + return; + } + if (resultBean instanceof CarOcrDataBean) { + CarOcrDataBean bean = (CarOcrDataBean) resultBean; + ToastUtil.centered(getContext(), "OCRCar返回:" + bean.getData().get(0).getPlateNumber()); + mAgentWeb.getJsAccessEntrace().quickCallJs("callOCRCarResult", new Gson().toJson(bean)); + } + } + + @Override + public void onUSCError(String operationType, int code, String msg) { + if (ErrorMsg.ERROR_USER_CANCEL.getIndex() != code) { + ToastUtil.centered(getContext(), String.format("错误码%s || %s", code, msg)); + } + mAgentWeb.getJsAccessEntrace().quickCallJs("callErrorResult", operationType, String.valueOf(code), msg); + } + }; + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + usComponentSDK.onActivityResult(requestCode, resultCode, data); + if (requestCode == 15015 && resultCode == Activity.RESULT_OK) { + if (data == null) return; + String stringExtra = data.getStringExtra(CameraScan.SCAN_RESULT); + mAgentWeb.getJsAccessEntrace().quickCallJs("callScanCodeResult", stringExtra); + return; + } + if (resultCode == Activity.RESULT_OK) { + if (null == webViewPresenter.mFilePathCallback) return; + switch (requestCode) { + case WebViewPresenter.RESULT_CODE: + if (webViewPresenter.photoFile == null || !webViewPresenter.photoFile.exists()) + return; + webViewPresenter.ysBitmap(); + return; + case WebViewPresenter.SELECT_IMG_CODE: + case WebViewPresenter.SELECT_FILE_CODE: + webViewPresenter.onActivityResultAboveL(requestCode, resultCode, data); + return; + } + } + if (webViewPresenter.mFilePathCallback != null) { + webViewPresenter.onActivityResultAboveL(requestCode, resultCode, data); +// webViewPresenter.mFilePathCallback.onReceiveValue(null); + webViewPresenter.mFilePathCallback = null; + } + super.onActivityResult(requestCode, resultCode, data); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (mAgentWeb.handleKeyEvent(keyCode, event)) return true; + return super.onKeyDown(keyCode, event); + } + + + private GPSLocationListener getGPSLocationListener() { + return new GPSLocationListener() { + @Override + public void onLocationChanged(Location location) { + ToastUtil.centered(getContext(), "调用位置更新" + location.toString()); + if (location != null) { + mAgentWeb.getJsAccessEntrace().quickCallJs("callLocationResult", location.getLongitude() + "", location.getLatitude() + ""); + } + } + + @Override + public void stopLocation() { + ToastUtil.centered(getContext(), "调用停止位置更新"); + if (mAgentWeb == null) return; + try { + mAgentWeb.getJsAccessEntrace().quickCallJs("callLocationError", "-102", "停止定位"); + } catch (Exception e) { + e.printStackTrace(); + ToastUtil.centered(getContext(), "ERROR:" + e.getMessage()); + finish(); + } + } + }; + } + + /** + * 需要进行检测的权限数组 + */ + protected String[] needPermissions = { + Manifest.permission.CAMERA, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.CALL_PHONE, + Manifest.permission.ACCESS_NETWORK_STATE + }; + + @Override + public void onGranted() { + initData(); + } + + @Override + public void onDenied(List deniDPermission) { + showMissingPermissionDialog(); + } + + private class AndroidMethodInterface { + + @JavascriptInterface + public void startLocation() { + LocationGPSManage manage = LocationGPSManage.getInstance(); + if (gpsLocationListener == null) { + gpsLocationListener = getGPSLocationListener(); + } + manage.addGPSLocationListener(gpsLocationListener); + try { + manage.startGPSLocation(getContext()); + } catch (RuntimeException e) { + ToastUtil.centered(getContext(), "没有权限,请先授权定位权限!"); + showMissingPermissionDialog(); + } + } + + @JavascriptInterface + public void stopLocation() { +// ToastUtil.centered(getContext(),"H5调用了停止定位"); + LocationGPSManage manage = LocationGPSManage.getInstance(); + if (gpsLocationListener == null) { + gpsLocationListener = getGPSLocationListener(); + } + manage.removeGPSLocationListener(gpsLocationListener); + manage.stopLocation(); + } + + /** + * 获取用户信息,为Base64转码的Json对象 + * Json格式:{"userCode":"警号","userName":"姓名","idCardNum":"身份证号","deptCode":"组织机构代码","deptName":"组织机构代码名称"} + */ + @JavascriptInterface + public String getUserInfo() { +// try { +// return calculateInterface.getJiaMi(appID, secret); +// } catch (RemoteException e) { +// e.printStackTrace(); +// return ""; +// } + UserData userData = RuanseeApplication.getUserData(); + Map param = new HashMap<>(); + param.put("userCode", userData.getUserCode()); + param.put("userName", userData.getUserName()); + param.put("idCardNum", userData.getIdCardNum()); + param.put("deptCode", userData.getDeptCode()); + param.put("deptName", userData.getDeptName()); + String s = new Gson().toJson(param); + return JiaMi.desCrypto(s.getBytes(), appID, secret); + } + + /** + * TODO 该方法不能弹出选择框,此方法是在JS调用选择文件方法之前调用的。在使用JS调选择文件时将根据此方法的配置做对应操作 + * 配置上传文件选择项。此方法再调用上传文件的事件之前调用,如果不调用则默认 selfRealization = false , 其他参数默认为 true + * 详情查看 {@link WebViewPresenter#mWebChromeClient} 的 onShowFileChooser(WebView, ValueCallback , FileChooserParams ) 方法 + * + * @param selfRealization 是否由JS自己实现文件选择上传。 + * PS: true:由JS自己实现,Android原生不做操作,不会弹出选择框,.值为false时将原生代码将拦截操作并根据下面参数配置弹出选择框。 + * @param isCamera PS:是否支持相机拍照: true = 支持相机拍照上传,false = 不支持相机拍照上传,值为false时弹出框将没有相机选项 + * @param isDCIM PS:是否支持相册选择: true = 支持相册选择上传,false = 不支持相册选择上传,值为false时弹出框将没有相册选项 + * @param isFileSelection PS:是否支持文件选择: true = 支持文件选择上传,false = 不支持文件选择上传,值为false时弹出框将没有文件选择选项 + * TODO 当且仅当 selfRealization = true && (isCamera | isDCIM | isFileSelection ) 只有一个为 true 时 将没有弹框,直接跳转对应操作 + */ + @JavascriptInterface + public void setUploadFileOptions(boolean selfRealization, boolean isCamera, boolean isDCIM, boolean isFileSelection) { + if (webViewPresenter.selectFileOptions == null) { + webViewPresenter.selectFileOptions = new SelectFileOptions(selfRealization, isCamera, isDCIM, isFileSelection); + } else { + webViewPresenter.selectFileOptions.configureOptions(selfRealization, isCamera, isDCIM, isFileSelection); + } + } + + /** + * 调用返回按钮 + */ + @JavascriptInterface + public void onBack() { + if (mAgentWeb.back()) return; + finish(); + } + + /** + * 控制APP标题栏显示隐藏 + * + * @param isShow true = 显示 || false = 隐藏 + */ + @JavascriptInterface + public void isTitleBlock(boolean isShow) { + runOnUiThread(new Runnable() { + @Override + public void run() { + if (isShow) { + visibleView(viewBinding.baseTitle); + } else { + goneView(viewBinding.baseTitle); + } + } + }); + } + + /** + * 退出到主页 + */ + @JavascriptInterface + public void exitToHome() { + finish(); + } + + /** + * 设置状态栏颜色及状态栏图标字体颜色深浅模式 + * + * @param statusBarColor 状态栏颜色 值为字符串 格式为:#ffffff + * @param isBlackFontColor 是否为 true 为黑色字体 | false 为白色字体 + */ + @JavascriptInterface + public void setSystemStatusBarStyle(String statusBarColor, boolean isBlackFontColor) { + int i = strToTextColor(statusBarColor, "#3255E3"); + runOnUiThread(new Runnable() { + @Override + public void run() { + StatusBarUtil.setStatusBarColor(getActivity(), i, isBlackFontColor); + try { + ColorDrawable drawable = new ColorDrawable(i); + viewBinding.vTopSeize.setBackground(drawable); + viewBinding.baseTitle.setBackground(drawable); + if (isBlackFontColor) { + viewBinding.contentTitle.setTextColor(getColors(R.color.colorGrey8)); + viewBinding.leftImage.setImageDrawable(getDrawable(R.drawable.ic_back_b)); + viewBinding.rightImage.setImageDrawable(getDrawable(R.drawable.icon_over_back)); + viewBinding.btnRefresh.setImageDrawable(getDrawable(R.drawable.icon_refresh_grad)); + } else { + viewBinding.contentTitle.setTextColor(getColors(R.color.colorWhite)); + viewBinding.leftImage.setImageDrawable(getDrawable(R.drawable.back_cliener)); + viewBinding.rightImage.setImageDrawable(getDrawable(R.drawable.icon_over)); + viewBinding.btnRefresh.setImageDrawable(getDrawable(R.drawable.icon_refresh)); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + /** + * @color:后台返回的色值 + * @defaultColor:ui默认的色值 + */ + private int strToTextColor(String color, String defaultColor) { + if (StringUtil.isNullOrEmpty(color)) { + return Color.parseColor(defaultColor); + } + if (!StringUtil.isNullOrEmpty(color) && (color.length() == 7) && (color.startsWith("#"))) { + return Color.parseColor(color); + } else { + return Color.parseColor(defaultColor); + } + } + + @JavascriptInterface + public String toName() { + return "callByAndroid"; + } + + /** + * 弹出提示框 + * + * @param title 提示标题 + * @param msg 提示内容 + * @param lxryName 联系人员 + * @param lxryPhone 联系电话 + */ + @JavascriptInterface + public void showNetPermission(String title, String msg, String lxryName, String lxryPhone) { + webViewPresenter.showLoadWebError(title, msg, lxryName, lxryPhone); + } + + /** + * 刷新页面 + */ + @JavascriptInterface + public void reloadPage() { + reloadPageAndroid(); + } + + /** + * 扫码 + */ + @JavascriptInterface + public void scanCode() { + Intent intent = new Intent(getContext(), ScanCodeActivity.class); + startActivityForResult(intent, 15015); + } + + /** + * 刷新页面 + */ + private void reloadPageAndroid() { + if (mAgentWeb == null) return; + //拿到这个页面,最后一次加载的url + String lastLoadUrl = mAgentWeb.getWebCreator().getWebView().getUrl(); + LogUtils.w("最后加载链接", lastLoadUrl); + //停止上次刷新 + mAgentWeb.getUrlLoader().stopLoading(); +// AgentWebConfig.removeAllCookies(); + AgentWebConfig.clearDiskCache(getContext()); + mAgentWeb.getUrlLoader().loadUrl(lastLoadUrl); + if (myHandler != null && lastLoadUrl != null) { + myHandler.sendEmptyMessageDelayed(-55, 50); + } + } + + /** + * 打开人像比对 + */ + @JavascriptInterface + public void goPersonFaceModule() { + usComponentSDK.openFaceIdentifyComponent(OpenAppActivity.this); + } + + /** + * 打开NFC组件 + */ + @JavascriptInterface + public void goNFCModule() { + usComponentSDK.openNFCComponent(OpenAppActivity.this); + } + + /** + * 打开OCR组件 + */ + @JavascriptInterface + public void goOCRCarModule() { + usComponentSDK.openOcrCarComponent(OpenAppActivity.this); + } + + /** + * 打开OCR组件 + */ + @JavascriptInterface + public void goOCRSfzModule() { + usComponentSDK.openOcrSfzComponent(OpenAppActivity.this); + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/OpinionsSuggestionsActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/OpinionsSuggestionsActivity.java new file mode 100644 index 0000000..27a2010 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/OpinionsSuggestionsActivity.java @@ -0,0 +1,206 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import android.app.Activity; +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.view.View; +import android.widget.TextView; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityOpinionsSuggestionsBinding; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.util.ParamMap; + +import org.json.JSONException; +import org.json.JSONObject; + +import okhttp3.MediaType; +import okhttp3.RequestBody; + +/** + * 意见反馈 + */ +public class OpinionsSuggestionsActivity extends BaseViewBindActivity { + private Drawable selectBJ; + private String appId; + private int feedType = 1; + + @Override + protected ActivityOpinionsSuggestionsBinding getViewBinding() { + return ActivityOpinionsSuggestionsBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + selectBJ = getDrawables(R.drawable.mancolor_round_button); + customClickListener = new CustomClickListener(500) { + @Override + public void onSingleClick(View v) { + bindViewClick(v); + } + }; + setViewOnClickListener(viewBinding.tvGrjy); + setViewOnClickListener(viewBinding.tvRjwt); + setViewOnClickListener(viewBinding.tvYjwt); + setViewOnClickListener(viewBinding.tvQt); + setViewOnClickListener(viewBinding.btnSelectApp); + setViewOnClickListener(viewBinding.baseTitle.titleleft); + setViewOnClickListener(viewBinding.btnSubmit); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void start() { + viewBinding.baseTitle.leftImage.setImageDrawable(getDrawables(R.drawable.back_cliener)); + viewBinding.baseTitle.contentTitle.setText("意见反馈"); + viewBinding.baseTitle.rightText.setText("我的反馈"); + setViewOnClickListener(viewBinding.baseTitle.titleright); + invisibleView(viewBinding.vFkyy); + } + + @Override + protected void bindViewClick(View v) { + switch (v.getId()) { + case R.id.titleright: + startActivity(new Intent(getContext(),MySuggestionsListActivity.class)); + break; + case R.id.titleleft: + finish(); + break; + case R.id.tv_grjy: + resetBackground(viewBinding.tvGrjy); + feedType = 1; + invisibleView(viewBinding.vFkyy); + break; + case R.id.tv_rjwt: + resetBackground(viewBinding.tvRjwt); + visibleView(viewBinding.vFkyy); + feedType = 2; + break; + case R.id.tv_yjwt: + resetBackground(viewBinding.tvYjwt); + invisibleView(viewBinding.vFkyy); + feedType = 3; + break; + case R.id.tv_qt: + resetBackground(viewBinding.tvQt); + invisibleView(viewBinding.vFkyy); + feedType = 4; + break; + case R.id.btn_select_app: + startActivityForResult(new Intent(getContext(), SelectAppActivity.class), 15104); + break; + case R.id.btn_submit: + save(); + break; + } + } + + private void save() { + if (feedType == 2 && StringUtil.isNullOrEmpty(appId)) { + ToastUtil.centered(getContext(), "请先选择应用"); + return; + } + String editText = getEditText(viewBinding.editTitle); + if (StringUtil.isNullOrEmpty(editText)) { + ToastUtil.centered(getContext(), "请输入反馈标题!"); + return; + } + String editText1 = getEditText(viewBinding.editContent); + if (StringUtil.isNullOrEmpty(editText1)) { + ToastUtil.centered(getContext(), "请输入反馈内容!"); + return; + } + ParamMap paramMap = new ParamMap(); + paramMap.put("applicationId", appId); + paramMap.put("alarmSignal", RuanseeApplication.getUserData().getUserCode()); + paramMap.put("alarmName", RuanseeApplication.getUserData().getUserName()); + paramMap.put("type", feedType+""); + paramMap.put("title", editText); + paramMap.put("content", editText1); + paramMap.put("applicationName", getTextString(viewBinding.tvSelectApp)); + String replace = new Gson().toJson(paramMap.apply()); + MediaType mediaType = MediaType.Companion.parse("application/json;charset=utf-8"); + RequestBody stringBody = RequestBody.Companion.create(replace, mediaType); + baseShowDialog("正在提交,请稍后..."); + ApiModel.request(RetrofitService.getBaseInstance().addFeedBack(stringBody), new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + baseDismissDialog(); + LogUtils.e(TAG,msg); + ToastUtil.centered(getContext(),msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + baseDismissDialog(); + // {"code":20011,"data":null,"msg":"提交成功!"} + LogUtils.w(TAG,result.toString()); + ApiModel.uploadOperationLog("3","3","用户提交了一条意见建议"); + try { + JSONObject o = new JSONObject(result.toString()); + ToastUtil.centered(getContext(),TypConversion.getJsonStr(o,"msg")); + if (TypConversion.getJsonInt(o,"code",-1) == 20011){ + finish(); + } + } catch (JSONException e) { + e.printStackTrace(); + ToastUtil.centered(getContext(),e.getMessage()); + } + } + }); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable @org.jetbrains.annotations.Nullable Intent data) { + if (requestCode == 15104 && resultCode == Activity.RESULT_OK) { + if (data == null) { + ToastUtil.centered(getContext(), "选择应用错误!"); + return; + } + appId = data.getStringExtra("appId"); + String appName = data.getStringExtra("appName"); + viewBinding.tvSelectApp.setText(appName); + } + super.onActivityResult(requestCode, resultCode, data); + } + + private void resetBackground(TextView selectView) { + viewBinding.tvGrjy.setBackground(getDrawables(R.drawable.card_white_round_4_bk)); + viewBinding.tvGrjy.setTextColor(getColors(R.color.colorGrey6)); + viewBinding.tvRjwt.setBackground(getDrawables(R.drawable.card_white_round_4_bk)); + viewBinding.tvRjwt.setTextColor(getColors(R.color.colorGrey6)); + viewBinding.tvYjwt.setBackground(getDrawables(R.drawable.card_white_round_4_bk)); + viewBinding.tvYjwt.setTextColor(getColors(R.color.colorGrey6)); + viewBinding.tvQt.setBackground(getDrawables(R.drawable.card_white_round_4_bk)); + viewBinding.tvQt.setTextColor(getColors(R.color.colorGrey6)); + selectView.setBackground(selectBJ); + selectView.setTextColor(getColors(R.color.colorWhite)); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/PlayVideosActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/PlayVideosActivity.java new file mode 100644 index 0000000..3cceb2f --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/PlayVideosActivity.java @@ -0,0 +1,110 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import android.os.Build; +import android.os.Bundle; +import android.view.View; + +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ycgis.macall.personalcenter.databinding.ActivityPlayVideosBinding; + +import java.util.concurrent.TimeUnit; + +import cn.jzvd.Jzvd; +import io.reactivex.Observable; +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; + +/** + * 播放视频 + */ +public class PlayVideosActivity extends BaseViewBindActivity { + + private String url; + @Override + protected ActivityPlayVideosBinding getViewBinding() { + return ActivityPlayVideosBinding.inflate(getLayoutInflater()); + } + + @Override + protected void init() { + if (Build.VERSION.SDK_INT >= 19) { + View decorView = getWindow().getDecorView(); + decorView.setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN + | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + } else { + View decorView = getWindow().getDecorView(); + int option = View.SYSTEM_UI_FLAG_FULLSCREEN; + decorView.setSystemUiVisibility(option); + } + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + url = getIntent().getStringExtra("url"); + } + + @Override + protected void start() { + if (StringUtil.isNullOrEmpty(url)){ + ToastUtil.centered(getContext(),"错误的视频地址"); + delayFinish(); + } + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + Jzvd.backPress(); + } + @Override + protected void onPause() { + super.onPause(); + Jzvd.releaseAllVideos(); + } + + /** + * 延时关闭当前Activity + */ + protected void delayFinish() { + delayFinish(1500); + } + + /** + * 延时关闭当前Activity + * + * @param millisecond 延迟关闭时间毫秒 + */ + protected void delayFinish(int millisecond) { + Observable.timer(millisecond, TimeUnit.MILLISECONDS) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(Long aLong) { + finish(); + } + + @Override + public void onError(Throwable e) { + + } + + @Override + public void onComplete() { + + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/ScanCodeActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/ScanCodeActivity.java new file mode 100644 index 0000000..8a1cf10 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/ScanCodeActivity.java @@ -0,0 +1,276 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import android.app.ActionBar; +import android.app.Activity; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.PointF; +import android.os.Bundle; +import android.provider.MediaStore; +import android.view.View; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.Binarizer; +import com.google.zxing.BinaryBitmap; +import com.google.zxing.ChecksumException; +import com.google.zxing.DecodeHintType; +import com.google.zxing.FormatException; +import com.google.zxing.LuminanceSource; +import com.google.zxing.MultiFormatReader; +import com.google.zxing.NotFoundException; +import com.google.zxing.RGBLuminanceSource; +import com.google.zxing.ReaderException; +import com.google.zxing.Result; +import com.google.zxing.common.GlobalHistogramBinarizer; +import com.google.zxing.common.HybridBinarizer; +import com.google.zxing.qrcode.QRCodeReader; +import com.king.zxing.CameraScan; +import com.king.zxing.CaptureActivity; +import com.king.zxing.DecodeConfig; +import com.king.zxing.DecodeFormatManager; +import com.king.zxing.analyze.MultiFormatAnalyzer; +import com.king.zxing.config.ResolutionCameraConfig; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.request.RequestCode; +import com.rs.macall.androidx.basemodel.utils.StatusBarUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.p.rxjava.ResultObserver; +import com.ycgis.macall.personalcenter.p.rxjava.UpdateUiOnSubscribe; +import com.ycgis.macall.personalcenter.util.FileUtils; +import com.ycgis.macall.personalcenter.util.ImageOptimizationUtil; +import com.ycgis.macall.personalcenter.util.UriUtils; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.TestOnly; + +import java.io.File; +import java.io.IOException; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; +import java.util.Vector; + +import io.reactivex.Observable; +import io.reactivex.ObservableEmitter; +import io.reactivex.ObservableOnSubscribe; +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; + +import static com.king.zxing.CameraScan.SCAN_RESULT; + +public class ScanCodeActivity extends CaptureActivity { + + @Override + public int getLayoutId() { + return R.layout.activity_scan_code; + } + + @Override + public void initCameraScan() { + super.initCameraScan(); + StatusBarUtil.setRootViewFitsSystemWindows(this, false); + //设置状态栏透明 + StatusBarUtil.setTranslucentStatus(this); +// ActionBar actionBar = getActionBar(); + setActionBar(null); + + //初始化解码配置 + DecodeConfig decodeConfig = new DecodeConfig(); + decodeConfig.setHints(DecodeFormatManager.DEFAULT_HINTS)//如果只有识别二维码的需求,这样设置效率会更高,不设置默认为DecodeFormatManager.DEFAULT_HINTS + .setFullAreaScan(false)//设置是否全区域识别,默认false + .setAreaRectRatio(0.8f)//设置识别区域比例,默认0.8,设置的比例最终会在预览区域裁剪基于此比例的一个矩形进行扫码识别 + .setAreaRectVerticalOffset(0)//设置识别区域垂直方向偏移量,默认为0,为0表示居中,可以为负数 + .setAreaRectHorizontalOffset(0);//设置识别区域水平方向偏移量,默认为0,为0表示居中,可以为负数 + + // 获取CameraScan,扫码相关的配置设置。CameraScan里面包含部分支持链式调用的方法,即调用返回是CameraScan本身的一些配置建议在startCamera之前调用。 + getCameraScan().setPlayBeep(true)//设置是否播放音效,默认为false + .setVibrate(true)//设置是否震动,默认为false + .setCameraConfig(new ResolutionCameraConfig(this))//设置相机配置信息,CameraConfig可覆写options方法自定义配置 + .setNeedAutoZoom(false)//二维码太小时可自动缩放,默认为false + .setNeedTouchZoom(true)//支持多指触摸捏合缩放,默认为true + .setDarkLightLux(45f)//设置光线足够暗的阈值(单位:lux),需要通过{@link #bindFlashlightView(View)}绑定手电筒才有效 + .setBrightLightLux(100f)//设置光线足够明亮的阈值(单位:lux),需要通过{@link #bindFlashlightView(View)}绑定手电筒才有效 + .bindFlashlightView(ivFlashlight)//绑定手电筒,绑定后可根据光线传感器,动态显示或隐藏手电筒按钮 + .setOnScanResultCallback(this)//设置扫码结果回调,需要自己处理或者需要连扫时,可设置回调,自己去处理相关逻辑 + .setAnalyzer(new MultiFormatAnalyzer(decodeConfig));//设置是否分析图片,默认为true。如果设置为false,相当于关闭了扫码识别功能 + +// 启动预览(如果是通过继承CaptureActivity或CaptureFragment实现的则无需调用startCamera) + getCameraScan().startCamera(); + findViewById(R.id.ivBack).setOnClickListener(v -> finish()); + findViewById(R.id.ivPhotoAlbum).setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + openSysAlbum(); + } + }); + } + + /** + * 打开系统相册 + */ + private void openSysAlbum() { + Intent albumIntent = new Intent(Intent.ACTION_PICK); + albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); + startActivityForResult(albumIntent, RequestCode.REQUEST_PHOTO_ALBUM); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable @org.jetbrains.annotations.Nullable Intent data) { + if (requestCode == RequestCode.REQUEST_PHOTO_ALBUM) { + if (data == null) { + ToastUtil.centered(this, "选择照片失败!"); + return; + } + String ss = UriUtils.getRealPathFromUri(this, data.getData()); + File photoFile = new File(ss); + if (!photoFile.exists()) { + ToastUtil.centered(ScanCodeActivity.this, "文件不存在!"); + return; + } + decodeQRCodeSync(photoFile); +// Bitmap bitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath()); +// if (bitmap == null){ +// ToastUtil.centered(ScanCodeActivity.this,"错误的图片!"); +// return; +// } +// decodeQRCodeSync(bitmap); + } + super.onActivityResult(requestCode, resultCode, data); + } + + private void decodeQRCodeSync(File file) { + Observable.create(new UpdateUiOnSubscribe(file) { + + @Override + public void subscribe(File date, @NotNull ObservableEmitter emitter) { + Bitmap decodeAbleBitmap = getDecodeAbleBitmap(date.getAbsolutePath()); + if (decodeAbleBitmap==null){ + emitter.onError(new Exception("错误的图片路径!")); + emitter.onComplete(); + return; + } + String s = syncDecodeQRCode(decodeAbleBitmap); + if (s == null){ + emitter.onError(new Exception("错误的图片路径!")); + emitter.onComplete(); + return; + } + emitter.onNext(s); + emitter.onComplete(); + } + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new ResultObserver("s") { + @Override + protected void onNext(String identifierKey, @NotNull String data) { + Intent intent = new Intent(); + intent.putExtra(SCAN_RESULT, data); + setResult(Activity.RESULT_OK, intent); + finish(); + } + + @Override + public void onError(@NotNull Throwable e) { + ToastUtil.centered(ScanCodeActivity.this, "识别失败!"); + } + }); + } + + + /** + * 扫码结果回调 + * + * @param result + * @return 返回false表示不拦截,将关闭扫码界面并将结果返回给调用界面; + * 返回true表示拦截,需自己处理逻辑。当isAnalyze为true时,默认会继续分析图像(也就是连扫)。 + * 如果只是想拦截扫码结果回调,并不想继续分析图像(不想连扫),请在拦截扫码逻辑处通过调 + * 用{@link CameraScan#setAnalyzeImage(boolean)}, + * 因为{@link CameraScan#setAnalyzeImage(boolean)}方法能动态控制是否继续分析图像。 + */ + @Override + public boolean onScanResultCallback(Result result) { + getCameraScan().setAnalyzeImage(false); + /* + * 因为setAnalyzeImage方法能动态控制是否继续分析图像。 + * + * 1. 因为分析图像默认为true,如果想支持连扫,返回true即可。 + * 当连扫的处理逻辑比较复杂时,请在处理逻辑前调用getCameraScan().setAnalyzeImage(false), + * 来停止分析图像,等逻辑处理完后再调用getCameraScan().setAnalyzeImage(true)来继续分析图像。 + * + * 2. 如果只是想拦截扫码结果回调自己处理逻辑,但并不想继续分析图像(即不想连扫),可通过 + * 调用getCameraScan().setAnalyzeImage(false)来停止分析图像。 + */ +// Intent intent = new Intent(); +// intent.putExtra("IdentifyingContent",result.getText()); +// setResult(Activity.RESULT_OK,intent); + + return super.onScanResultCallback(result); + } + + + + /** + * 将本地图片文件转换成可解码二维码的 Bitmap。为了避免图片太大,这里对图片进行了压缩。 + * + * @param picturePath 本地图片文件路径 + */ + public static Bitmap getDecodeAbleBitmap(String picturePath) { + try { + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; + BitmapFactory.decodeFile(picturePath, options); + int sampleSize = options.outHeight / 400; + if (sampleSize <= 0) { + sampleSize = 1; + } + options.inSampleSize = sampleSize; + options.inJustDecodeBounds = false; + + return BitmapFactory.decodeFile(picturePath, options); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + /** + * 同步解析bitmap二维码。该方法是耗时操作,请在子线程中调用。 + * + * @param bitmap 要解析的二维码图片 + * @return 返回二维码图片里的内容 或 null + */ + public static String syncDecodeQRCode(Bitmap bitmap) { + Result result; + RGBLuminanceSource source = null; + try { + int width = bitmap.getWidth(); + int height = bitmap.getHeight(); + int[] pixels = new int[width * height]; + bitmap.getPixels(pixels, 0, width, 0, 0, width, height); + source = new RGBLuminanceSource(width, height, pixels); + result = new MultiFormatReader().decode(new BinaryBitmap(new HybridBinarizer(source)), new EnumMap<>(DecodeHintType.class)); + return result.getText(); + } catch (Exception e) { + e.printStackTrace(); + if (source != null) { + try { + result = new MultiFormatReader().decode(new BinaryBitmap(new GlobalHistogramBinarizer(source)), new EnumMap<>(DecodeHintType.class)); + return result.getText(); + } catch (Throwable e2) { + e2.printStackTrace(); + } + } + return null; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/SelectAppActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/SelectAppActivity.java new file mode 100644 index 0000000..bb74fd1 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/SelectAppActivity.java @@ -0,0 +1,261 @@ +package com.ycgis.macall.personalcenter.v.activity; + + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; +import android.view.inputmethod.EditorInfo; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.decoration.MyDividerItemDecoration; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivitySelectAppBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.AppInfoBean; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.m.adapterbean.SelectRoleBean; +import com.ycgis.macall.personalcenter.m.requestbean.AppInfoModel; +import com.ycgis.macall.personalcenter.m.requestbean.BaseRequestModel; +import com.ycgis.macall.personalcenter.m.requestbean.PagingModel; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.v.adapter.SelectAppAdapter; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.TestOnly; + +import java.util.ArrayList; +import java.util.List; + +public class SelectAppActivity extends BaseViewBindActivity { + private int counts,pageNum,pageSize=20; + private String searchWord; + private SelectAppAdapter appAdapter; + private String appId,appName; + + @Override + protected ActivitySelectAppBinding getViewBinding() { + return ActivitySelectAppBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + viewBinding.selappRvList.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); + viewBinding.selappRvList.addItemDecoration(new MyDividerItemDecoration(getContext(),LinearLayoutManager.VERTICAL)); + SmartRefreshLayoutHelp.setRefreshAndLoad(getContext(),viewBinding.selappSrlRefresh); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void start() { + viewBinding.selappTitle.contentTitle.setText("选择应用"); + viewBinding.selappTitle.leftImage.setImageDrawable(getDrawable(R.drawable.back_cliener)); + viewBinding.selappTitle.titleleft.setOnClickListener(v -> finish()); + viewBinding.selappSearch.editQuery.setHint("输入应用名称进行搜索"); + viewBinding.selappTitle.rightText.setText("确定"); + viewBinding.selappTitle.titleright.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + if (StringUtil.isNullOrEmptyAll(appId,appName)){ + ToastUtil.centered(getContext(),"请先选择应用!"); + return; + } + Intent i = new Intent(); + i.putExtra("appId",appId); + i.putExtra("appName",appName); + setResult(Activity.RESULT_OK,i); + finish(); + } + }); + viewBinding.selappSearch.editQuery.setImeOptions(EditorInfo.IME_ACTION_SEARCH); + viewBinding.selappSearch.btnClean.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + viewBinding.selappSearch.editQuery.setText(""); + } + }); + + viewBinding.selappSearch.editQuery.setOnEditorActionListener((v, actionId, event) -> { + if (actionId == EditorInfo.IME_ACTION_SEARCH) { + searchWord = getEditText(viewBinding.selappSearch.editQuery); + viewBinding.selappSrlRefresh.autoRefresh(); + return true; + } + return false; + }); + + viewBinding.selappSearch.editQuery.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + if (s == null || StringUtil.isNullOrEmpty(s.toString())) { + goneView(viewBinding.selappSearch.btnClean); + return; + } + visibleView(viewBinding.selappSearch.btnClean); + } + }); + viewBinding.selappSrlRefresh.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull @NotNull RefreshLayout refreshLayout) { + if (pageSize*pageNum>=counts){ + viewBinding.selappSrlRefresh.finishLoadMoreWithNoMoreData(); + return; + } + pageNum++; + searchApp(); + } + + @Override + public void onRefresh(@NonNull @NotNull RefreshLayout refreshLayout) { + viewBinding.selappSrlRefresh.resetNoMoreData(); + pageNum=1; + searchApp(); + } + }); + viewBinding.selappSrlRefresh.autoRefresh(); + } + + private AppInfoBean error(int type,String msg){ + AppInfoBean b = new AppInfoBean(); + b.setBaseType(type); + b.setBaseMessage(msg); + return b; + } + + private void searchApp(){ + ApiModel.request(RetrofitService.getBaseInstance().selectAppList( searchWord, pageNum, pageSize), + new BaseRequestCallback>>() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(TAG,msg); + if (viewBinding.selappSrlRefresh.isRefreshing()){ + viewBinding.selappSrlRefresh.finishRefresh(); + AppInfoBean error = error(-1, msg); + List items = new ArrayList<>(); + items.add(error); + initData(items); + } + if (viewBinding.selappSrlRefresh.isLoading()){ + viewBinding.selappSrlRefresh.finishLoadMore(); + ToastUtil.centered(getContext(),msg); + } + } + + @Override + public void onRequestSuccess(BaseRequestModel> result) { + LogUtils.w(TAG,result.toString()); + if (result.getCode() == 20041){ + PagingModel data = result.getData(); + counts = data.getCounts(); + List items = data.getItems(); + for (AppInfoBean b : items) { + b.setBaseType(1); + } + if (viewBinding.selappSrlRefresh.isRefreshing()){ + viewBinding.selappSrlRefresh.finishRefresh(); + if (items.isEmpty()){ + items.add(error(0,"暂无应用")); + }else { + if (pageSize*pageNum>=counts){ + viewBinding.selappSrlRefresh.finishLoadMoreWithNoMoreData(); + } + } + initData(items); + } + if (viewBinding.selappSrlRefresh.isLoading()){ + viewBinding.selappSrlRefresh.finishLoadMore(); + if (!items.isEmpty()){ + appAdapter.addData(items); + if (pageSize*pageNum>=counts){ + viewBinding.selappSrlRefresh.finishLoadMoreWithNoMoreData(); + } + } + } + }else { + if (viewBinding.selappSrlRefresh.isRefreshing()){ + viewBinding.selappSrlRefresh.finishRefresh(); + AppInfoBean error = error(-1, result.getMsg()); + List items = new ArrayList<>(); + items.add(error); + initData(items); + } + if (viewBinding.selappSrlRefresh.isLoading()){ + viewBinding.selappSrlRefresh.finishLoadMore(); + ToastUtil.centered(getContext(),result.getMsg()); + } + } + } + }); + } + + private void initData(List items) { + if (appAdapter == null){ + appAdapter = new SelectAppAdapter(getContext(),items); + viewBinding.selappRvList.setAdapter(appAdapter); + appAdapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + AppInfoBean dataItem = appAdapter.getDataItem(pointer); + if (dataItem.getBaseType()!=1) return; + if (dataItem.isSelect()){ + dataItem.setSelect(false); + appAdapter.notifyItemChanged(pointer,5); + appId = ""; + appName = ""; + return; + } + List data = appAdapter.getData(); + for (int i = 0; i implements PermissionListener { + + private Handler myHandler; + + private final String[] permissionList = { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.CAMERA, + Manifest.permission.CHANGE_NETWORK_STATE, + Manifest.permission.ACCESS_NETWORK_STATE, + Manifest.permission.READ_PHONE_STATE}; + + @Override + protected ActivityStartBinding getViewBinding() { + return ActivityStartBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + myHandler = HandlerUtils.getActivity(this); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + //杏花公园 百汇 瑶东北村 B C 金葡萄A + @Override + protected void start() { + if (!this.isTaskRoot()) { + Intent mainIntent = getIntent(); + String action = mainIntent.getAction(); + if (mainIntent.hasCategory(Intent.CATEGORY_LAUNCHER) && action.equals(Intent.ACTION_MAIN)) { + finish(); + return; + } + } + Watermark.getInstance().clean(); + viewBinding.startMsg.setText("正在检测应用权限..."); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + requestPermissions(permissionList, this); + } else { + initPage(); + } + } + + private void initPage() { +// ParamMap map = new ParamMap(); +// map.put("主板",Build.BOARD); +// map.put("cpu指令集",Build.CPU_ABI); +// map.put("设备参数",Build.DEVICE); +// map.put("显示屏参数",Build.DISPLAY); +// map.put("硬件名称",Build.FINGERPRINT); +// map.put("硬件制造商",Build.MANUFACTURER ); +// map.put("手机制造商",Build.PRODUCT ); +// map.put("TYPE ",Build.TYPE ); +// LogUtils.e("设备信息:",new Gson().toJson(map.apply())); +// String ip = com.ycgis.macall.personalcenter.util.IPAddressUtils.getLocalIpAddress(); +// RuanseeApplication.getAppCache() +// RuanseeApplication.saveData("equipmentIP", ip); + getImei(); + viewBinding.startMsg.setText("正在初始化应用..."); + myHandler.sendEmptyMessageDelayed(1, 800); + } + + @SuppressLint({"MissingPermission", "HardwareIds"}) + private void getImei() { + String imei = RuanseeApplication.getAppCache().getImei(); + if (StringUtil.isNullOrEmpty(imei)) { + imei = ReadDeviceInfo.getDeviceId(getContext()); + if (StringUtil.isNullOrEmpty(imei)) { + imei = ReadDeviceInfo.getIMEI1(getContext()); + RuanseeApplication.getAppCache().setImei(imei); + } + } + String imsi = RuanseeApplication.getAppCache().getImsi(); + if (StringUtil.isNullOrEmpty(imsi)) { + imsi = ReadDeviceInfo.getIMSI(getContext(), 0); + if (StringUtil.isNullOrEmpty(imsi)) { + imsi = ReadDeviceInfo.getIMSI(getContext(), 1); + } + RuanseeApplication.getAppCache().setImsi(imsi); + } + } + + private void setFormal() { +// RuanseeApplication.getAppCache().setIpAndPort("192.168.43.183", "8081"); + RuanseeApplication.getAppCache().setIpAndPort("20.90.2.2", "80"); +// getAccessToken(); + if (RuanseeApplication.isHFVersion) { +// PService ps = new PService(this); +// try { +// viewBinding.tvLoadMsg.setText("单点登录成功!"); +// RuanseeApplication.getUserData().setUserCode(ps.getUserAccount()); +// RuanseeApplication.getUserData().setUserName(ps.getPoliceName()); +// RuanseeApplication.getUserData().setDeptCode(ps.getZZJGDm()); +// RuanseeApplication.getUserData().setDeptName(ps.getZZJGName()); +// RuanseeApplication.getUserData().setIdCardNum(ps.getSFZ()); +// if (!RuanseeApplication.getUserData().isValidOrNot()) { +// viewBinding.tvLoadMsg.setText("无效的用户!"); +// ysFinish(); +// return; +// } +// viewBinding.tvLoadMsg.setText("正在获取用户信息!"); +// getUserDeptName(); +// } catch (Exception e) { +// viewBinding.tvLoadMsg.setText("用户登录失败!获取用户失败!"); +// ysFinish(); +// } + } else { + boolean isUpdateAuthType = RuanseeApplication.getBooleanValue("isUpdateAuthType", false); + if (isUpdateAuthType) { + AuthSDK sdk = AuthSDK.getDefault(); + List types = new ArrayList<>(); + types.add(RuanseeApplication.getAppCache().getAuthType()); + AuthConfig config = AuthConfig.builder().setAuthTypes(types); + if (sdk == null) { + AuthSDK.init(RuanseeApplication.getAppCache().getSysmCode(), + getContext(), config); + AuthSDK.getDefault().startAuth(iTokenListener); + } else { + sdk.startAuth(config, iTokenListener); + } + } else { + AuthSDK.getDefault().getToken(0.8f, iTokenListener); + } + } + } + + private IAuthUserListener iTokenListener = new IAuthUserListener() { + + @Override + public void onAuthTaskCallback(@IAuthTaskType int authTaskType, int authCode, @Nullable @org.jetbrains.annotations.Nullable String authResult, + @Nullable @org.jetbrains.annotations.Nullable com.anhui.police.auth.AuthUser authUser, + @Nullable @org.jetbrains.annotations.Nullable String level) { + LogUtils.v(TAG, authCode + " : " + authResult); + if (authCode == 200) { + switch (authTaskType) { + case 0://getToken + case 2:// 绑定验证因子(手势、人脸) + AuthSDK.getDefault().getUserInfo(authResult, this); + RuanseeApplication.getAppCache().setToken(authResult); + RuanseeApplication.saveData("isUpdateAuthType",false); + break; + case 1://使用token换取用户信息 + setAppUserInfo(authUser); + break; + case 3://使用用户名密码、手势、数字证书、人脸等方式验证用户身份 + + break; + case 4:// 设置用户信息 + + break; + case 5://解绑 验证因子(手势) + + break; + default: + viewBinding.startMsg.setText(authResult); + ToastUtil.centered(StartActivity.this, "错误码:" + authCode + " mes: " + authResult); + AuthSDK.getDefault().startAuth(this); + break; + } + } else { + ToastUtil.centered(StartActivity.this, authResult); + if (authCode>=900&&authCode<1000) { + List types = new ArrayList<>(); + types.add(RuanseeApplication.getAppCache().getAuthType()); + AuthConfig config = AuthConfig.builder().setAuthTypes(types); + AuthSDK.getDefault().startAuth(config,iTokenListener); + return; + } + viewBinding.startMsg.setText(authResult); + ysFinish(); + } + } + }; + + private void setAppUserInfo(com.anhui.police.auth.AuthUser authUser){ + UserData userData = RuanseeApplication.getUserData(); + if (authUser == null) { + ToastUtil.centered(StartActivity.this, "获取用户数据失败!!!"); + return; + } + viewBinding.startMsg.setText("单点登录成功!"); + userData.setUserCode(authUser.getUserNum()); + userData.setUserName(authUser.getRealName()); + userData.setDeptCode(authUser.getOrgId()); + userData.setDeptName(authUser.getOrgName()); + userData.setIdCardNum(authUser.getCode()); + userData.setPhone1(authUser.getWorkPhone()); +// userData.setPhone2(authUser.getPhoneNum()); + userData.setPhoto(authUser.getProfilePhoto()); + userData.setPolice_role(authUser.getPoliceTypeName()); + if (!userData.isValidOrNot()) { + viewBinding.startMsg.setText("无效的用户!"); + ysFinish(); + return; + } + userData.setIp(RuanseeApplication.getAppCache().getLocalIp()); + ApiModel.uploadOperationLog("3","3","用户登录应用"); + + String substring = RuanseeApplication.getUserData().getDeptCode().substring(0, 4); + RuanseeApplication.getUserData().setDepartmentCode(substring); + RuanseeApplication.getUserData().setDepartmentName(AhdsAddressUtils.getAddressNameByCode(RuanseeApplication.getUserData().getDeptCode())); + initWatermark(); + viewBinding.startMsg.setText("正在获取用户信息!"); + myHandler.sendEmptyMessageDelayed(2, 800); + } + + private void initWatermark() { + Watermark instance = Watermark.getInstance(); + instance.clean(); + instance.addLabel(getString(R.string.app_name)) + .addLabel(String.format("%s(%s)", RuanseeApplication.getUserData().getUserName(), RuanseeApplication.getUserData().getUserCode())) + .addLabel(DateUitls.date2Str(new Date(),"yyyy-MM-dd")) + .setTextSize(14); + instance.show(getActivity()); + } + + private void ysFinish() { + Observable.timer(1500, TimeUnit.MILLISECONDS) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NotNull Disposable d) { + + } + + @Override + public void onNext(@NotNull Long aLong) { + finish(); + } + + @Override + public void onError(@NotNull Throwable e) { + + } + + @Override + public void onComplete() { + + } + }); + } + + @Override + public void handleMessage(Message msg) { + if (msg.what == 1) { + viewBinding.startMsg.setText("正在登录..."); +// setTestUer(); + setFormal(); + } else if (msg.what == 2) { + viewBinding.startMsg.setText("正在加载数据..."); + myHandler.sendEmptyMessageDelayed(3, 800); + } else if (msg.what == 3) { + viewBinding.AVLoadingIndicatorView.smoothToHide(); + startActivity(new Intent(getContext(), MainActivity.class)); + finish(); + } + } + + private void setTestUer() { +// RuanseeApplication.getAppCache().setIpAndPort("20.90.2.2", "80"); + RuanseeApplication.getAppCache().setIpAndPort("192.168.0.129", "8081"); +// RuanseeApplication.getAppCache().setIpAndPort("192.168.0.233", "8081"); +// RuanseeApplication.getAppCache().setIpAndPort("192.168.43.98", "8081"); + UserData userData = RuanseeApplication.getUserData(); + userData.setUserCode("999013"); + userData.setUserName("陈乐(测试账号)"); +// userData.setDeptCode("340112000000"); + userData.setDeptCode("340512000000"); + userData.setPhone1("18815654126"); + userData.setDeptName("安徽省公安厅科技信息化处应用指导科"); + userData.setIdCardNum("342422199306041413"); + String dept_name = "省厅"; + try { + String substring = RuanseeApplication.getUserData().getDeptCode().substring(0, 4); + RuanseeApplication.getUserData().setDepartmentCode(substring); + dept_name = AhdsAddressUtils.getAddressNameByCode(RuanseeApplication.getUserData().getDeptCode()); + RuanseeApplication.getUserData().setDepartmentName(dept_name); + } catch (Exception e) { + e.printStackTrace(); + } + + initWatermark(); + myHandler.sendEmptyMessageDelayed(2, 800); + } + + @Override + public void onGranted() { + initPage(); + + } + + @Override + public void onDenied(List deniDPermission) { + showMissingPermissionDialog(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/SuggestionsDetailsActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/SuggestionsDetailsActivity.java new file mode 100644 index 0000000..8ea20d6 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/SuggestionsDetailsActivity.java @@ -0,0 +1,85 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import android.os.Bundle; +import android.text.Html; + +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivitySuggestionsDetailsBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.FeedbackBean; +import com.ycgis.macall.personalcenter.p.app.AppCache; + +/** + * 意见反馈详情 + */ +public class SuggestionsDetailsActivity extends BaseViewBindActivity { + private FeedbackBean bean; + + @Override + protected ActivitySuggestionsDetailsBinding getViewBinding() { + return ActivitySuggestionsDetailsBinding.inflate(getLayoutInflater()); + } + + @Override + protected void init() { + + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + bean = (FeedbackBean) getIntent().getSerializableExtra("dataModel"); + } + + @Override + protected void start() { + viewBinding.include2.contentTitle.setText("反馈详情"); + viewBinding.include2.leftImage.setImageDrawable(getDrawables(R.drawable.back_cliener)); + viewBinding.include2.titleleft.setOnClickListener(v->finish()); + if (bean == null){ + ToastUtil.centered(getContext(),"未知错误!"); + return; + } + viewBinding.suggestionsTvTitle.setText(bean.getTitleStr()); + viewBinding.suggestionsContent.setText(bean.getContentStr()); + viewBinding.suggestionsTvTime.setText(bean.getCreateTime()); + viewBinding.suggestionsTvType.setText(bean.getTypeStr()); + + if (StringUtil.isNullOrEmpty(bean.getApplicationName())){ + goneView(viewBinding.suggestionsBqAppName); + }else { + visibleView(viewBinding.suggestionsBqAppName); + viewBinding.suggestionsBqAppName.setText(bean.getApplicationName()); + } + if (bean.getReplyStatus() == 1){ + visibleView(viewBinding.suggestionsReply); + StringBuffer str = new StringBuffer(); + str.append("

") + .append(bean.getReplyContent().replace("/prod-api/profile", AppCache.BASE_IMAGE_URL+"profile")) + .append("

"); + viewBinding.replyContent.loadDataWithBaseURL("", str.toString(), "text/html","UTF-8", ""); + +// viewBinding.replyContent.loadUrl(bean.getReplyContent()); +// viewBinding.replyContent.setText(Html.fromHtml(bean.getReplyContent())); + viewBinding.replyTime.setText(bean.getUpdateTime()); + viewBinding.replyUser.setText(bean.getReplier()); + viewBinding.suggestionsTvReply.setText("已回复"); + viewBinding.suggestionsTvReply.setBackground(getDrawables(R.drawable.bk_ls)); + viewBinding.suggestionsTvReply.setTextColor(getColors(R.color.colorGreen6)); + }else { + goneView(viewBinding.suggestionsReply); + viewBinding.suggestionsTvReply.setText("未回复"); + viewBinding.suggestionsTvReply.setBackground(getDrawables(R.drawable.bk_gray)); + viewBinding.suggestionsTvReply.setTextColor(getColors(R.color.colorGrey6)); + } + } + + + +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/UpdateDeptActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/UpdateDeptActivity.java new file mode 100644 index 0000000..4e4f262 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/UpdateDeptActivity.java @@ -0,0 +1,313 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.LinearLayoutManager; + +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.KeyEvent; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.widget.TextView; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.decoration.MyDividerItemDecoration; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityUpdateDeptBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.m.adapterbean.OrgBean; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.callback.EditTextWatcherListener; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.v.adapter.SelectDeptAdapter; + +import org.jetbrains.annotations.NotNull; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class UpdateDeptActivity extends BaseViewBindActivity { + private SelectDeptAdapter adapter; + private int total, page, pageSize = 50; + private String searchWord; + private String imei = "", imsi = ""; + private String selectDeptCode; + + @Override + protected ActivityUpdateDeptBinding getViewBinding() { + return ActivityUpdateDeptBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + viewBinding.updateDeptTitle.contentTitle.setText(R.string.applyUpdateDept); + viewBinding.updateDeptTitle.rightText.setText(R.string.submitApply); + viewBinding.updateDeptTitle.leftImage.setImageDrawable(getDrawables(R.drawable.back_cliener)); + viewBinding.updateDeptTitle.titleleft.setOnClickListener(v -> finish()); + viewBinding.updateDeptTitle.titleright.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + submitDept(); + } + }); + MyDividerItemDecoration myDividerItemDecoration = new MyDividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL); + myDividerItemDecoration.setBottom(true); + viewBinding.updateDeptList.addItemDecoration(myDividerItemDecoration); + viewBinding.updateDeptList.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); + SmartRefreshLayoutHelp.setRefreshAndLoad(getContext(), viewBinding.updateDeptSrl); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + imei = getIntent().getStringExtra("imei"); + imsi = getIntent().getStringExtra("imsi"); +// ToastUtil.centered(getContext(),String.format("imei:%s || imsi:%s",imei,imsi)); + } + + @Override + protected void start() { + viewBinding.updateDeptSearch.editQuery.setImeOptions(EditorInfo.IME_ACTION_SEARCH); + //处理搜索事件 + viewBinding.updateDeptSearch.editQuery.setOnEditorActionListener((v, actionId, event) -> { + if (actionId == EditorInfo.IME_ACTION_SEARCH) { + searchWord = getEditText(viewBinding.updateDeptSearch.editQuery); + viewBinding.updateDeptSrl.autoRefresh(); + return true; + } + return false; + }); + //处理清空事件 + viewBinding.updateDeptSearch.btnClean.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + viewBinding.updateDeptSearch.editQuery.setText(""); + searchWord = ""; + } + }); + //处理 清空按钮 + viewBinding.updateDeptSearch.editQuery.addTextChangedListener(new EditTextWatcherListener() { + @Override + public void afterTextChanged(Editable s) { + if (s == null || StringUtil.isNullOrEmpty(s.toString())) { + goneView(viewBinding.updateDeptSearch.btnClean); + return; + } + visibleView(viewBinding.updateDeptSearch.btnClean); + } + }); + // + viewBinding.updateDeptSrl.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull @NotNull RefreshLayout refreshLayout) { + if (total <= page * pageSize) { + viewBinding.updateDeptSrl.finishLoadMoreWithNoMoreData(); + return; + } + page++; + getDeptData(); + } + + @Override + public void onRefresh(@NonNull @NotNull RefreshLayout refreshLayout) { + viewBinding.updateDeptSrl.resetNoMoreData(); + page = 1; + getDeptData(); + } + }); + viewBinding.updateDeptSrl.autoRefresh(); + } + + private OrgBean getErrorBean(int type, String msg) { + OrgBean bean = new OrgBean(); + bean.setBaseType(type); + bean.setBaseMessage(msg); + return bean; + } + + private void submitDept() { + if (StringUtil.isNullOrEmpty(selectDeptCode)) { + ToastUtil.centered(getContext(), "请先选择单位这提交申请!"); + return; + } + baseShowFaseDialong("重要提醒", "正在提交申请,请勿执行其他操作,申请成功后需等待管路员审核!"); + Map param = new HashMap<>(); + param.put("token", RuanseeApplication.getAppCache().getToken()); + param.put("clientType", "MOBILE"); + param.put("deviceFlags", imei); + param.put("imsi1", imsi); + param.put("sysCode", RuanseeApplication.getAppCache().getSysmCode()); + param.put("orgCode", selectDeptCode); + ApiModel.request(RetrofitService.getBaseInstance().getLoginType("http://20.90.2.2/UniAuth/api/sso/v1/auditUserOrg", param), + new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + baseDismissDialog(); + ToastUtil.centered(getContext(), msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + baseDismissDialog(); + LogUtils.w(TAG, result.toString()); + try { + JSONObject object = new JSONObject(result.toString()); + int code = TypConversion.getJsonInt(object, "code", -1); + if (code == 200) { + ToastUtil.centered(getContext(),"申请提交成功,请等待审核!"); + } else { + ToastUtil.centered(getContext(), StringUtil.get(TypConversion.getJsonStr(object, "msg"), TypConversion.getJsonStr(object, "content"))); + } + } catch (JSONException e) { + e.printStackTrace(); + ToastUtil.centered(getContext(), e.getMessage()); + } + } + }); + } + + private void getDeptData() { +// Map param = new HashMap<>(); +// param.put("token", RuanseeApplication.getAppCache().getToken()); +// param.put("clientType", "MOBILE"); +// param.put("deviceFlags", imei); +// param.put("imsi1", imsi); +// param.put("sysCode", RuanseeApplication.getAppCache().getSysmCode()); +// param.put("page", pageSize + ""); +// param.put("pageSize", page + ""); +// param.put("size", pageSize + ""); +// param.put("orgName", searchWord); + ApiModel.request(RetrofitService.getBaseInstance().getDeptList(searchWord, page, pageSize), + new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + ToastUtil.centered(getContext(), msg); + if (viewBinding.updateDeptSrl.isRefreshing()) { + viewBinding.updateDeptSrl.finishRefresh(); + List data = new ArrayList<>(); + OrgBean errorBean = getErrorBean(-1, msg); + data.add(errorBean); + initData(data); + } + if (viewBinding.updateDeptSrl.isLoading()) { + viewBinding.updateDeptSrl.finishLoadMore(); + } + } + + @Override + public void onRequestSuccess(JsonObject result) { + try { + JSONObject object = new JSONObject(result.toString()); + String code = TypConversion.getJsonStr(object, "code"); + if (!code.equals("20041")) { + if (viewBinding.updateDeptSrl.isRefreshing()) { + viewBinding.updateDeptSrl.finishRefresh(); + List data = new ArrayList<>(); + OrgBean errorBean = getErrorBean(-1, TypConversion.getJsonStr(object, "msg")); + data.add(errorBean); + initData(data); + } + if (viewBinding.updateDeptSrl.isLoading()) { + viewBinding.updateDeptSrl.finishLoadMore(); + } + return; + } + JSONObject dataJson = object.getJSONObject("data"); + total = TypConversion.getJsonInt(dataJson, "counts", 0); + Gson gson = new Gson(); + List data = new ArrayList<>(); + JSONArray array = dataJson.getJSONArray("items"); + for (int i = 0; i < array.length(); i++) { + JSONObject object1 = array.getJSONObject(i); + OrgBean bean = gson.fromJson(object1.toString(), OrgBean.class); + bean.setBaseType(1); + data.add(bean); + } + if (viewBinding.updateDeptSrl.isRefreshing()) { + if (data.isEmpty()) { + OrgBean errorBean = getErrorBean(0, "暂无数据!"); + data.add(errorBean); + } + initData(data); + viewBinding.updateDeptSrl.finishRefresh(); + } + if (viewBinding.updateDeptSrl.isLoading()) { + if (!data.isEmpty()) { + adapter.addData(data); + } + viewBinding.updateDeptSrl.finishLoadMore(); + } + if (total <= page * pageSize) { + viewBinding.updateDeptSrl.finishLoadMoreWithNoMoreData(); + } + } catch (JSONException e) { + e.printStackTrace(); + ToastUtil.centered(getContext(), e.getMessage()); + if (viewBinding.updateDeptSrl.isRefreshing()) { + viewBinding.updateDeptSrl.finishRefresh(); + List data = new ArrayList<>(); + OrgBean errorBean = getErrorBean(-1, e.getMessage()); + data.add(errorBean); + initData(data); + } + if (viewBinding.updateDeptSrl.isLoading()) { + viewBinding.updateDeptSrl.finishLoadMore(); + } + } + } + }); + } + + private void initData(List data) { + if (adapter == null) { + adapter = new SelectDeptAdapter(getContext(), data); + viewBinding.updateDeptList.setAdapter(adapter); + adapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + OrgBean dataItem = adapter.getDataItem(pointer); + if (dataItem.isSelect()) { + return; + } + for (int i = 0; i < adapter.getItemCount(); i++) { + OrgBean dataItem1 = adapter.getDataItem(i); + if (dataItem1.isSelect()) { + dataItem1.setSelect(false); + adapter.notifyItemChanged(i, 12); + break; + } + } + dataItem.setSelect(true); + adapter.notifyItemChanged(pointer, 12); + selectDeptCode = dataItem.getOrgCode(); + } + }); + } else { + adapter.upData(data); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/UpdatePasswordActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/UpdatePasswordActivity.java new file mode 100644 index 0000000..e201c47 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/UpdatePasswordActivity.java @@ -0,0 +1,167 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.os.Bundle; +import android.util.Log; +import android.view.Gravity; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; + +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.utils.DimensionConvert; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityUpdatePasswordBinding; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Map; + +public class UpdatePasswordActivity extends BaseViewBindActivity { + private String imei = "", imsi = ""; + + @Override + protected ActivityUpdatePasswordBinding getViewBinding() { + return ActivityUpdatePasswordBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + viewBinding.btnSave.setOnClickListener(customClickListener); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + imei = getIntent().getStringExtra("imei"); + imsi = getIntent().getStringExtra("imsi"); + + } + + @Override + protected void start() { + viewBinding.updateTitle.contentTitle.setText("修改账号密码"); + viewBinding.updateTitle.leftImage.setImageDrawable(getDrawable(R.drawable.back_cliener)); + viewBinding.updateTitle.titleleft.setOnClickListener(v -> finish()); + } + + @Override + protected void bindViewClick(View v) { + if (v.getId() == R.id.btn_save) { + String pass = getEditText(viewBinding.editPassword); + String pass1 = getEditText(viewBinding.editNewPassword1); + String pass2 = getEditText(viewBinding.editNewPassword2); + + if (StringUtil.isNullOrEmpty(pass)) { + shoeDialogTitle("原密码不能为空!"); + return; + } + if (StringUtil.isNullOrEmpty(pass1)) { + shoeDialogTitle("请输入新密码!"); + return; + } + if (!isPassword(getEditText(viewBinding.editNewPassword1))) { + shoeDialogTitle("密码格式不正确!"); + return; + } + if (StringUtil.isNullOrEmpty(pass2)) { + shoeDialogTitle("请再次确认新密码!"); + return; + } + if (!pass1.equals(pass2)) { +// viewBinding.editNewPassword2.setText(""); + viewBinding.editNewPassword2.setFocusable(true); + viewBinding.editNewPassword2.setFocusableInTouchMode(true); + shoeDialogTitle("两次密码不一样!!!"); + return; + } + updatePassword(pass, pass1); + } + } + + private void updatePassword(String ymm, String xmm) { + Map param = new HashMap<>(); + param.put("token", RuanseeApplication.getAppCache().getToken()); + param.put("clientType", "MOBILE"); + param.put("deviceFlags", imei); + param.put("imsi1", imsi); + param.put("sysCode", RuanseeApplication.getAppCache().getSysmCode()); + param.put("oldPwd", ymm); + param.put("newPwd", xmm); + baseShowDialog("正在提交请稍后..."); + ApiModel.request(RetrofitService.getBaseInstance().getLoginType("http://20.90.2.2/UniAuth/api/sso/v1/updatePwd", param), new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + baseDismissDialog(); + ToastUtil.centered(UpdatePasswordActivity.this, msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + baseDismissDialog(); + ApiModel.uploadOperationLog("3","3", "修改了统一日志登录密码"); + try { + JSONObject object = new JSONObject(result.toString()); + if (TypConversion.getJsonStr(object, "code").equals("200")) { + ToastUtil.centered(UpdatePasswordActivity.this, TypConversion.getJsonStr(object, "content")); + finish(); + return; + } + ToastUtil.centered(UpdatePasswordActivity.this, TypConversion.getJsonStr(object, "content")); + } catch (JSONException e) { + e.printStackTrace(); + ToastUtil.centered(UpdatePasswordActivity.this, "解析失败!请联系管理员!"); + } + } + }); + } + + public void shoeDialogTitle(String message) { + Dialog dialog = new AlertDialog.Builder(this) + .setTitle("重要提示") + .setMessage("\n\t\t\t" + message) + .setIcon(R.drawable.icon_jg) + .create(); + Window dialogWindow = dialog.getWindow(); + // 设置 dialog 显示的位置 + dialogWindow.setGravity(Gravity.CENTER); + int ss = DimensionConvert.dip2px(this, 20); + // 设置 dialog 的边距 + dialogWindow.getDecorView().setPadding(DimensionConvert.dip2px(this, 8), ss, 0, ss); + // 设置 标题 + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + // 获取 LayoutParams + WindowManager.LayoutParams lp = dialogWindow.getAttributes(); + // 设置 dialog 宽度高度 + lp.width = DimensionConvert.dip2px(this, 300); + lp.height = WindowManager.LayoutParams.WRAP_CONTENT; + dialogWindow.setAttributes(lp); + dialog.show(); + } + + + public boolean isPassword(String password) { + if (StringUtil.isNullOrEmpty(password)) return false; + // 大小写加数字 + + String regex = "(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])[a-zA-Z0-9]{8,15}"; +// String regex = "/^[a-zA-Z\\d]+$/"; + return password.matches(regex); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/WorkbenchCenterActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/WorkbenchCenterActivity.java new file mode 100644 index 0000000..5ca5a59 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/WorkbenchCenterActivity.java @@ -0,0 +1,382 @@ +package com.ycgis.macall.personalcenter.v.activity; + +import android.app.Activity; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.view.KeyEvent; +import android.view.View; +import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; +import android.widget.LinearLayout; +import android.widget.PopupWindow; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.utils.DimensionConvert; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; + +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener; + +import com.ycgis.macall.personalcenter.R; + +import com.ycgis.macall.personalcenter.databinding.ActivityWorkbenchCenterBinding; + +import com.ycgis.macall.personalcenter.m.adapterbean.AppInfoBean; +import com.ycgis.macall.personalcenter.m.adapterbean.SelectAddressBean; +import com.ycgis.macall.personalcenter.m.enumbean.AppOpenType; +import com.ycgis.macall.personalcenter.m.requestbean.AppInfoModel; +import com.ycgis.macall.personalcenter.m.requestbean.BaseRequestModel; +import com.ycgis.macall.personalcenter.m.requestbean.PagingModel; +import com.ycgis.macall.personalcenter.m.requestbean.WorkbenchModel; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.callback.SelectReturnCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.util.ToThirdPartyAppUtils; +import com.ycgis.macall.personalcenter.v.adapter.WorkbenchCenterAdapter; +import com.ycgis.macall.personalcenter.v.custom.SelectAddressPopupWindow; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import io.reactivex.Observable; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; + +/** + * 工作台 + */ +public class WorkbenchCenterActivity extends BaseViewBindActivity { + private int total, pageNum, pageSize = 30; + private String searchWord, selectCode; + private WorkbenchCenterAdapter appListAdapter; + private ToThirdPartyAppUtils appUtils; + private boolean isSt = false; + private List commonAppName; + private SelectAddressPopupWindow selectAddressPopupWindow; + + @Override + protected ActivityWorkbenchCenterBinding getViewBinding() { + return ActivityWorkbenchCenterBinding.inflate(getLayoutInflater()); + } + + @Override + protected void init() { + SmartRefreshLayoutHelp.setRefreshAndLoad(getContext(), viewBinding.appCenterSrlRefresh); +// viewBinding.appCenterRvList.addItemDecoration(new GridDividerItemDecoration(getContext())); + setViewOnClickListener(viewBinding.btnSwitchSs); + setViewOnClickListener(viewBinding.btnSwitchSsV); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void start() { + viewBinding.leftImage.setImageDrawable(getDrawables(R.drawable.back_cliener)); + viewBinding.leftImage.setOnClickListener(v -> finish()); + viewBinding.appCenterSrlRefresh.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull @NotNull RefreshLayout refreshLayout) { + if (total <= pageSize * pageNum) { + refreshLayout.finishLoadMoreWithNoMoreData(); + return; + } + pageNum++; + getAppData(); + } + + @Override + public void onRefresh(@NonNull @NotNull RefreshLayout refreshLayout) { + refreshLayout.resetNoMoreData(); + pageNum = 1; + getAppData(); + } + }); + viewBinding.search.editQuery.setImeOptions(EditorInfo.IME_ACTION_SEARCH); + queryEvent(); + selectCode = RuanseeApplication.getUserData().getDepartmentCode() + "00000000"; + if ("3400".equals(RuanseeApplication.getUserData().getDepartmentCode())) { + viewBinding.btnSwitchSs.setText("省厅"); + } else { + viewBinding.btnSwitchSs.setText(RuanseeApplication.getUserData().getDepartmentName()); + } + selectCode = RuanseeApplication.getUserData().getDepartmentCode() + "00000000"; + viewBinding.appCenterSrlRefresh.autoRefresh(); + } + + private void queryEvent() { + viewBinding.search.btnClean.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + viewBinding.search.editQuery.setText(""); + searchWord = null; + goneView(viewBinding.search.btnClean); + } + }); + viewBinding.search.editQuery.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_SEARCH) { + searchWord = getEditText(viewBinding.search.editQuery); + viewBinding.appCenterSrlRefresh.autoRefresh(); + return true; + } + return false; + } + }); + viewBinding.search.editQuery.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + if (s == null || StringUtil.isNullOrEmpty(s.toString())) { + goneView(viewBinding.search.btnClean); + searchWord = null; + return; + } + visibleView(viewBinding.search.btnClean); + } + }); + } + + @Override + protected void onPause() { + super.onPause(); + baseDismissDialog(); + } + + + @Override + protected void bindViewClick(View v) { + switch (v.getId()) { + case R.id.btn_switch_ss: + case R.id.btn_switch_ss_v: + viewBinding.btnSwitchSs.setClickable(false); + viewBinding.btnSwitchSsV.setClickable(false); + if (RuanseeApplication.getUserData().getDepartmentCode().equals("3400")) { + showSelectAll(); + } else { + if (selectCode.startsWith("3400")) { + viewBinding.btnSwitchSs.setText(RuanseeApplication.getUserData().getDepartmentName()); + selectCode = RuanseeApplication.getUserData().getDepartmentCode() + "00000000"; + } else { + selectCode = "340000000000"; + viewBinding.btnSwitchSs.setText("省厅"); + } + viewBinding.appCenterSrlRefresh.autoRefresh(); + } + break; + } + } + + private void showSelectAll() { + showSelectAll(getActivity(), viewBinding.btnSwitchSs, new PopupWindow.OnDismissListener() { + @Override + public void onDismiss() { + yanshishezhi(); + WindowManager.LayoutParams lp = getActivity().getWindow().getAttributes(); + lp.alpha = 1f; + getActivity().getWindow().setAttributes(lp); + } + }, message -> { + selectCode = message.getCode() + "00000000"; + viewBinding.btnSwitchSs.setText(message.getName()); + viewBinding.appCenterSrlRefresh.autoRefresh(); + }); + } + + private void yanshishezhi() { + Observable.timer(800, TimeUnit.MILLISECONDS) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NotNull Disposable d) { + + } + + @Override + public void onNext(@NotNull Long aLong) { + + } + + @Override + public void onError(@NotNull Throwable e) { + + } + + @Override + public void onComplete() { + viewBinding.btnSwitchSs.setClickable(true); + viewBinding.btnSwitchSsV.setClickable(true); + } + }); + } + + private AppInfoBean error(int type, String msg) { + AppInfoBean b = new AppInfoBean(); + b.setBaseType(type); + b.setBaseMessage(msg); + return b; + } + + private void initError(int type, String msg) { + if (viewBinding.appCenterSrlRefresh.isRefreshing()) { + viewBinding.appCenterSrlRefresh.finishRefresh(); + AppInfoBean error = error(type, msg); + List items = new ArrayList<>(); + items.add(error); + initData(items); + } + if (viewBinding.appCenterSrlRefresh.isLoading()) { + viewBinding.appCenterSrlRefresh.finishLoadMore(); + ToastUtil.centered(getContext(), msg); + } + } + + /** + * 选择省厅 地市 + * + * @param activity 当前Activity + * @param view 显示View + * @param dismissListener 取消监听 + * @param selectReturnCallback 选择监听 + */ + public void showSelectAll(Activity activity, View view, PopupWindow.OnDismissListener dismissListener, SelectReturnCallback selectReturnCallback) { + if (selectAddressPopupWindow == null) { + int i = getResources().getDisplayMetrics().heightPixels - DimensionConvert.dip2px(activity, 88) - DimensionConvert.dip2px(activity, 118); + selectAddressPopupWindow = new SelectAddressPopupWindow(activity, selectReturnCallback, LinearLayout.LayoutParams.MATCH_PARENT, + i); + } + //监听窗口的焦点事件,点击窗口外面则取消显示 + selectAddressPopupWindow.getContentView().setOnFocusChangeListener((v, hasFocus) -> { + if (!hasFocus) { + selectAddressPopupWindow.dismiss(); + } + }); + selectAddressPopupWindow.setOnDismissListener(dismissListener); + //popWindow消失监听方法 + WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); + lp.alpha = 0.7f; + activity.getWindow().setAttributes(lp); + //设置默认获取焦点 + selectAddressPopupWindow.setFocusable(true); + int xOffset = 10; + //以某个控件的x和y的偏移量位置开始显示窗口 + selectAddressPopupWindow.showAsDropDown(view, xOffset, 30); + //如果窗口存在,则更新 + selectAddressPopupWindow.update(); + } + + private void getAppData() { + ApiModel.request("getAppListData", RetrofitService.getBaseInstance().applicationPage(selectCode, pageNum, pageSize, searchWord, 0), + new BaseRequestCallback>>() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(TAG, msg); + initError(-1, msg); + } + + @Override + public void onRequestSuccess(BaseRequestModel> result) { + LogUtils.w(TAG, result.toString()); + if (result.getCode() == 20041) { + PagingModel data = result.getData(); + total = data.getCounts(); + List items = data.getItems(); + if (items.isEmpty()) { + initError(0, "暂无应用"); + return; + } + for (int i = 0; i < items.size(); i++) { + items.get(i).setBaseType(1); + } + if (viewBinding.appCenterSrlRefresh.isRefreshing()) { + viewBinding.appCenterSrlRefresh.finishRefresh(); + if (pageSize * pageNum >= total) { + viewBinding.appCenterSrlRefresh.finishLoadMoreWithNoMoreData(); + } + initData(items); + } + if (viewBinding.appCenterSrlRefresh.isLoading()) { + viewBinding.appCenterSrlRefresh.finishLoadMore(); + appListAdapter.addData(items); + if (pageSize * pageNum >= total) { + viewBinding.appCenterSrlRefresh.finishLoadMoreWithNoMoreData(); + } + } + } else { + if (result.getCode() == 20040) { + total = 0; + initError(0, "暂无应用"); + return; + } + initError(-1, result.getMsg()); + } + } + }); + + } + + private void initData(List items) { + if (items.size() == 1) { + int baseType = items.get(0).getBaseType(); + if (baseType != 1) { + viewBinding.appCenterRvList.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); + }else { + viewBinding.appCenterRvList.setLayoutManager(new GridLayoutManager(getContext(), 4)); + } + }else { + viewBinding.appCenterRvList.setLayoutManager(new GridLayoutManager(getContext(), 4)); + } + if (appListAdapter == null) { + appListAdapter = new WorkbenchCenterAdapter(getContext(), items); + viewBinding.appCenterRvList.setAdapter(appListAdapter); + appListAdapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + AppInfoBean dataItem = appListAdapter.getDataItem(pointer); + if (appUtils == null) { + appUtils = new ToThirdPartyAppUtils(getContext()); + } + baseShowDialog("正在打开应用,请稍后。。。"); + appUtils.skipApp(dataItem, AppOpenType.LOGIN); + } + }); + } else { + appListAdapter.upData(items); + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/ApplyDetailsActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/ApplyDetailsActivity.java new file mode 100644 index 0000000..f25ed43 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/ApplyDetailsActivity.java @@ -0,0 +1,290 @@ +package com.ycgis.macall.personalcenter.v.activity.applyfo; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.LinearLayoutManager; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.util.Log; +import android.view.View; +import android.widget.EditText; +import android.widget.TextView; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityApplyDetailsBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.ApplyAuditBean; +import com.ycgis.macall.personalcenter.m.adapterbean.ApplyBean; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.v.adapter.ApplyAuditRecordAdapter; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import okhttp3.MediaType; +import okhttp3.RequestBody; + +public class ApplyDetailsActivity extends BaseViewBindActivity { + //2 待审核 3 审核详情 + private int operatingType; + private String data, applyId; + private ApplyAuditRecordAdapter adapter; + + @Override + protected ActivityApplyDetailsBinding getViewBinding() { + return ActivityApplyDetailsBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + viewBinding.titleleft.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + finish(); + } + }); + LinearLayoutManager manager = new LinearLayoutManager(getContext()); + manager.setOrientation(LinearLayoutManager.VERTICAL); + viewBinding.rvList.setLayoutManager(manager); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + if (savedInstanceState == null) { + data = getIntent().getStringExtra("data"); + operatingType = getIntent().getIntExtra("operatingType", 1); + savePageCacheData("data", data); + savePageCacheData("operatingType", operatingType); + } else { + data = savedInstanceState.getString("data"); + operatingType = savedInstanceState.getInt("operatingType"); + } + if (operatingType == 1) { + viewBinding.contentTitle.setText("记录详情"); + goneView(viewBinding.llOperation); + } else if (operatingType == 2) { + viewBinding.contentTitle.setText("审核申请"); + visibleView(viewBinding.llOperation); + setViewOnClickListener(viewBinding.btnPass); + setViewOnClickListener(viewBinding.btnReject); + } else if (operatingType == 3) { + viewBinding.contentTitle.setText("记录详情"); + goneView(viewBinding.llOperation); + goneView(viewBinding.btnRevoke); + } + } + + @Override + protected void start() { + ApplyBean bean = new Gson().fromJson(data, ApplyBean.class); + viewBinding.tvType.setText(bean.getTypeStr2()); + viewBinding.tvReasonTitle.setText(bean.getTypeStr2() + "原因:"); + viewBinding.tvApplicant.setText(String.format("%s(%s)", bean.getName(), bean.getCode())); + viewBinding.tvDeptName.setText(bean.getDeptName()); + viewBinding.tvSelectApp.setText(bean.getSysName()); + viewBinding.tvSelectRole.setText(bean.getRoleName()); + viewBinding.tvUserIdCardNum.setText(bean.getIdCordNum()); + viewBinding.editPhone.setText(bean.getPhone()); + viewBinding.editReason.setText(bean.getApplyReason()); + applyId = bean.getId(); + getAuditRecord(applyId); + if (bean.getState() == 1) { + goneView(viewBinding.llOperation); + if (operatingType != 3) { + visibleView(viewBinding.btnRevoke); + setViewOnClickListener(viewBinding.btnRevoke); + } + } + } + + @Override + protected void bindViewClick(View v) { + if (v.getId() == R.id.btn_pass) { + submit(true, ""); + } else if (v.getId() == R.id.btn_reject) { + showDialog(); + } else if (v.getId() == R.id.btn_revoke) {//申请撤销 + Intent intent = new Intent(getContext(), InitiateApplyForActivity.class); + intent.putExtra("data", data); + startActivity(intent); + } + } + + /** + * 不通过为0 通过为 1 + * + * @param isPass 是否通过 + */ + private void submit(boolean isPass, String opinion) { + baseShowDialog("正在提交,请稍后..."); + Map param = new HashMap<>(); + param.put("applyId", applyId); + param.put("auditStatus", String.valueOf(isPass ? 1 : 0)); + param.put("opinion", opinion); + baseShowDialog("正在查询审核记录,请稍后..."); + Map headMap = new HashMap<>(1); + headMap.put("app-yysq-token", RuanseeApplication.getAppCache().getApply_token()); + MediaType mediaType = MediaType.Companion.parse("application/json;charset=utf-8"); + RequestBody stringBody = RequestBody.Companion.create(new Gson().toJson(param), mediaType); + ApiModel.request(RetrofitService.getBaseInstance().applyPost(ApplyForMainActivity.BASE_URL + "audit/save", headMap, stringBody), new BaseRequestCallback() { + + @Override + public void onRequestFailure(String msg) { + Log.e(TAG, msg); + baseDismissDialog(); + ToastUtil.centered(getContext(), msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + Log.w(TAG, result.toString()); + baseDismissDialog(); + //{"msg":"操作成功","code":200} + try { + JSONObject object = new JSONObject(result.toString()); + ToastUtil.centered(getContext(), TypConversion.getJsonStr(object, "msg")); + int code = TypConversion.getJsonInt(object, "code", -1); + if (code != 200) { + return; + } + setResult(Activity.RESULT_OK); + finish(); + } catch (JSONException e) { + e.printStackTrace(); + ToastUtil.centered(getContext(), "msg"); + } + } + }); + + + } + + private void getErrorList(int type, String msg) { + List baseBeans = new ArrayList<>(); + BaseBean baseBean = new BaseBean() { + }; + baseBean.setBaseType(type); + baseBean.setBaseMessage(msg); + baseBeans.add(baseBean); + initData(baseBeans); + } + + private void getAuditRecord(String applyId) { + baseShowDialog("正在查询审核记录,请稍后..."); + Map param = new HashMap<>(); + param.put("pageNum", 1); + param.put("pageSize", 10); + param.put("applyId", applyId); + Map headMap = new HashMap<>(1); + headMap.put("app-yysq-token", RuanseeApplication.getAppCache().getApply_token()); + ApiModel.request(RetrofitService.getBaseInstance().applyGet(ApplyForMainActivity.BASE_URL + "audit/dxlist", headMap, param), + new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + Log.e(TAG, msg); + baseDismissDialog(); + ToastUtil.centered(getContext(), msg); + getErrorList(-1, msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + Log.w(TAG, result.toString()); + baseDismissDialog(); + try { + JSONObject object = new JSONObject(result.toString()); + int code = TypConversion.getJsonInt(object, "code", -1); + if (code != 200) { + getErrorList(-1, TypConversion.getJsonStr(object, "msg")); + return; + } + JSONArray rows = TypConversion.getJSONArray(object, "rows"); + if (rows == null || rows.length() <= 0) { + getErrorList(0, "没有审核记录"); + return; + } + Type type = new TypeToken>() { + }.getType(); + List lsit = new Gson().fromJson(rows.toString(), type); + if (lsit == null || lsit.isEmpty()) { + getErrorList(0, "没有审核记录"); + return; + } + List dataList = new ArrayList<>(); + for (ApplyAuditBean bean : lsit) { + bean.setBaseType(1); + dataList.add(bean); + } + initData(dataList); + + } catch (JSONException e) { + e.printStackTrace(); + getErrorList(-1, e.getMessage()); + } + } + }); + } + + private void initData(List dataList) { + if (adapter == null) { + adapter = new ApplyAuditRecordAdapter(getContext(), dataList); + viewBinding.rvList.setAdapter(adapter); + } else { + adapter.upData(dataList); + } + } + + private void showDialog() { + View view = getLayoutInflater().inflate(R.layout.dialog_input, null, false); + Dialog dialog = new AlertDialog.Builder(getContext()) + .setView(view).create(); + dialog.show(); + TextView tvTitle = dialog.findViewById(R.id.tv_title); + tvTitle.setText("驳回原因"); + EditText viewById = dialog.findViewById(R.id.edit_input); + viewById.setHint("请输入驳回原因"); + dialog.findViewById(R.id.btn_submit).setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + Editable text = viewById.getText(); + if (text == null) { + ToastUtil.centered(getContext(), "请输入驳回原因!"); + return; + } + if (StringUtil.isNullOrEmpty(text.toString())) { + ToastUtil.centered(getContext(), "请输入驳回原因!"); + return; + } + dialog.dismiss(); + submit(false, text.toString()); + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/ApplyForMainActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/ApplyForMainActivity.java new file mode 100644 index 0000000..440293c --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/ApplyForMainActivity.java @@ -0,0 +1,301 @@ +package com.ycgis.macall.personalcenter.v.activity.applyfo; + +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.listener.OnRefreshListener; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityApplyForMainBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.ActionBean; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.app.UserData; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.v.adapter.ApplyForMainAdapter; + +import org.jetbrains.annotations.NotNull; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ApplyForMainActivity extends BaseViewBindActivity { + private ApplyForMainAdapter applyForMainAdapter; + + public static final String BASE_PHOTO_URL = "http://20.90.2.2"; + public static final String BASE_URL = BASE_PHOTO_URL + "/yysq_app_out/"; + +// public static final String BASE_PHOTO_URL = "http://192.168.0.110:8086"; +// public static final String BASE_URL = BASE_PHOTO_URL + "/app/"; + + private Map actionBeanMap; + + @Override + protected ActivityApplyForMainBinding getViewBinding() { + return ActivityApplyForMainBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + @Override + protected void init() { + GridLayoutManager manager = new GridLayoutManager(getContext(), 2); + manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int position) { + int itemViewType = applyForMainAdapter.getItemViewType(position); + if (itemViewType == 1) { + return 1; + } + return 2; + } + }); + LinearLayoutManager manager1 = new LinearLayoutManager(getContext()); + manager1.setOrientation(LinearLayoutManager.VERTICAL); + viewBinding.rvAppList.setLayoutManager(manager1); + viewBinding.ivExit.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + finish(); + } + }); + SmartRefreshLayoutHelp.setPullDownToRefresh(getContext(), viewBinding.srlRefresh); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void start() { + UserData userData = RuanseeApplication.getUserData(); + viewBinding.tvUserName.setText(String.format("你好!%s警官(%s)", userData.getUserName(), userData.getUserCode())); + viewBinding.tvUserDeptName.setText(userData.getDeptName()); + viewBinding.srlRefresh.setOnRefreshListener(new OnRefreshListener() { + @Override + public void onRefresh(@NonNull @NotNull RefreshLayout refreshLayout) { + getData(); + } + }); + viewBinding.srlRefresh.autoRefresh(); + } + + private void loginError(int type, String msg) { + List dataList = new ArrayList<>(); + BaseBean baseBean = new BaseBean() { + }; + baseBean.setBaseType(type); + baseBean.setBaseMessage(msg); + dataList.add(baseBean); + initData(dataList); + } + + private void getData() { + String apply_token = RuanseeApplication.getAppCache().getApply_token(); + if (StringUtil.isNullOrEmpty(apply_token)) { +// ApiModel.request(RetrofitService.getBaseInstance().applyLogin(BASE_URL + "login", "064922"), + ApiModel.request(RetrofitService.getBaseInstance().applyLogin(BASE_URL + "login", RuanseeApplication.getUserData().getUserCode()), +// ApiModel.request(RetrofitService.getBaseInstance().applyLogin(BASE_URL + "login","ahst"), + new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(TAG, msg); + ToastUtil.centered(getContext(), msg); + viewBinding.srlRefresh.finishRefresh(); + loginError(-1, msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + LogUtils.w(TAG, result.toString()); + viewBinding.srlRefresh.finishRefresh(); + try { + JSONObject jsonObject = new JSONObject(result.toString()); + int code = TypConversion.getJsonInt(jsonObject, "code", -1); + if (code != 200) { + loginError(-1, TypConversion.getJsonStr(jsonObject, "msg")); + return; + } + JSONObject data = TypConversion.getJSONObject(jsonObject, "data"); + String token = TypConversion.getJsonStr(data, "token"); + RuanseeApplication.getAppCache().setApply_token(token); + testIndex(token); + } catch (JSONException e) { + e.printStackTrace(); + loginError(-1, e.getMessage()); + } + } + }); + } else { + testIndex(apply_token); + } + + actionBeanMap = new HashMap<>(); + ActionBean bean1 = new ActionBean(); + bean1.setBaseType(1); + bean1.setName("申请应用"); + bean1.setaClass(InitiateApplyForActivity.class); + bean1.setIconId(R.drawable.ic_ybss); + actionBeanMap.put("申请应用", bean1); + +// dataList.add(bean1); + ActionBean bean6 = new ActionBean(); + bean6.setBaseType(1); + bean6.setName("我的申请"); + bean6.setaClass(MyApplyForActivity.class); + bean6.setIconId(R.drawable.ic_usercenter); + + actionBeanMap.put("我的申请", bean6); +// dataList.add(bean6); + ActionBean bean3 = new ActionBean(); + bean3.setBaseType(1); + bean3.setaClass(ToBeReviewedActivity.class); + bean3.addParam("operatingType", 2); + bean3.setName("待审核"); + bean3.setIconId(R.drawable.ic_transit); + actionBeanMap.put("待审核", bean3); + +// dataList.add(bean3); + ActionBean bean4 = new ActionBean(); + bean4.setBaseType(1); + bean4.setaClass(ToBeReviewedActivity.class); + bean4.addParam("operatingType", 3); + bean4.setName("审核记录"); + bean4.setIconId(R.drawable.ic_zhyy); + actionBeanMap.put("审核记录", bean4); + +// dataList.add(bean4); + ActionBean bean5 = new ActionBean(); + bean5.setBaseType(1); + bean5.setaClass(ApplyProcessActivity.class); + bean5.setName("申请流程"); + bean5.setIconId(R.drawable.ic_zazdr); + actionBeanMap.put("申请流程", bean5); +// dataList.add(bean5); +// initData(dataList); + } + + private void setTestUer() { + RuanseeApplication.getAppCache().setIpAndPort("20.90.2.2", "80"); + UserData userData = RuanseeApplication.getUserData(); + userData.setUserCode("ahst"); + userData.setUserName("陈乐"); + userData.setDeptCode("340012000000"); + userData.setDeptName("省厅"); + userData.setIdCardNum(""); + } + + private void testIndex(String token) { + Map headMap = new HashMap<>(1); + headMap.put("app-yysq-token", token); + ApiModel.request(RetrofitService.getBaseInstance().applyGet(BASE_URL + "index", headMap, new HashMap<>()), + new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(TAG, msg); + ToastUtil.centered(getContext(), msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + LogUtils.w(TAG, result.toString()); + try { + JSONObject object = new JSONObject(result.toString()); + int code = TypConversion.getJsonInt(object, "code", -1); + if (code != 200) { + ToastUtil.centered(getContext(), TypConversion.getJsonStr(object, "msg")); + return; + } + JSONArray data = TypConversion.getJSONArray(object, "data"); + if (data == null) { + ToastUtil.centered(getContext(), "没有权限"); + return; + } + List dataList = new ArrayList<>(); + for (int i = 0; i < data.length(); i++) { + JSONObject jsonObject = TypConversion.getJSONObject(data, i); + if (jsonObject == null) continue; + String name = TypConversion.getJsonStr(jsonObject, "name"); + if (!"Model".equals(name)) { + continue; + } + JSONArray children = TypConversion.getJSONArray(jsonObject, "children"); + for (int j = 0; j < children.length(); j++) { + JSONObject jsonObject1 = TypConversion.getJSONObject(children, j); + if (jsonObject1 == null) continue; + JSONObject meta1 = TypConversion.getJSONObject(jsonObject1, "meta"); + String title1 = TypConversion.getJsonStr(meta1, "title"); + ActionBean bean = actionBeanMap.get(title1); + if (bean == null) { + Log.e(TAG, "没有:" + title1); + continue; + } + dataList.add(bean); + } + } + if (dataList.isEmpty()) { + BaseBean baseBean = new BaseBean() { + }; + baseBean.setBaseType(0); + baseBean.setBaseMessage("暂无应用"); + dataList.add(baseBean); + } + initData(dataList); + } catch (JSONException e) { + e.printStackTrace(); + } + } + }); + } + + private void initData(List dataList) { + if (applyForMainAdapter == null) { + applyForMainAdapter = new ApplyForMainAdapter(getContext(), dataList); + viewBinding.rvAppList.setAdapter(applyForMainAdapter); + applyForMainAdapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + BaseBean dataItem = applyForMainAdapter.getDataItem(pointer); + if (dataItem instanceof ActionBean) { + ActionBean bean = (ActionBean) dataItem; + if (bean.getaClass() == null) { + ToastUtil.centered(getContext(), "正在紧急开发中!"); + return; + } + Intent intent = bean.setIntentParam(new Intent(getContext(), bean.getaClass())); + startActivity(intent); + } + } + }); + } else { + applyForMainAdapter.upData(dataList); + } + viewBinding.srlRefresh.finishRefresh(); + viewBinding.srlRefresh.setEnableRefresh(false); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/ApplyProcessActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/ApplyProcessActivity.java new file mode 100644 index 0000000..4f30588 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/ApplyProcessActivity.java @@ -0,0 +1,38 @@ +package com.ycgis.macall.personalcenter.v.activity.applyfo; + +import androidx.appcompat.app.AppCompatActivity; + +import android.os.Bundle; + +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityApplyProcessBinding; + +public class ApplyProcessActivity extends BaseViewBindActivity { + + @Override + protected ActivityApplyProcessBinding getViewBinding() { + return ActivityApplyProcessBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void start() { + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/InitiateApplyForActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/InitiateApplyForActivity.java new file mode 100644 index 0000000..1517e72 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/InitiateApplyForActivity.java @@ -0,0 +1,274 @@ +package com.ycgis.macall.personalcenter.v.activity.applyfo; + + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.View; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityInitiateApplyForBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.ApplyBean; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import okhttp3.MediaType; +import okhttp3.RequestBody; + +/** + * 申请撤销应用权限 + */ +public class InitiateApplyForActivity extends BaseViewBindActivity { + /** + * 用于缓存选择的用户和角色。 + * key:应用ID + * value : {"应用名称","角色名"} + */ + private Map selectValue; + + private String selectData; + private String appId; + private String data; + + @Override + protected ActivityInitiateApplyForBinding getViewBinding() { + return ActivityInitiateApplyForBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + viewBinding.contentTitle.setText("申请应用"); + viewBinding.titleleft.setOnClickListener(customClickListener); + viewBinding.btnSubmit.setOnClickListener(customClickListener); + goneView(viewBinding.llRole); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + if (savedInstanceState == null) { + data = getIntent().getStringExtra("data"); + } + } + + @Override + protected void start() { + if (StringUtil.hasContent(data)) { + ApplyBean bean = new Gson().fromJson(data, ApplyBean.class); + if (bean != null) { + viewBinding.spSpinner.setText("撤销"); + viewBinding.tvReasonTitle.setText("撤销原因:"); + viewBinding.editReason.setHint("请输入撤销原因:"); + viewBinding.editPhone.setText(bean.getPhone()); + viewBinding.tvSelectApp.setText(String.format("%s(%s)",bean.getSysName(),bean.getRoleName())); + viewBinding.tvSelectApp.setOnClickListener(null); + viewBinding.tvSelectJs.setOnClickListener(null); + appId = bean.getId(); + viewBinding.contentTitle.setText("撤销权限申请"); + selectValue = new HashMap<>(); + selectValue.put(appId,new String[]{bean.getSysName(),bean.getRoleName()}); + } + }else { + viewBinding.btnSelectApp.setOnClickListener(customClickListener); + viewBinding.tvSelectJs.setOnClickListener(customClickListener); + } + } + @Override + protected void bindViewClick(View v) { + switch (v.getId()) { + case R.id.titleleft: + isExit(); + break; + case R.id.btn_select_app: + Intent intent = new Intent(getContext(), SelectSystemActivity.class); + intent.putExtra("operationType", 1); + if (StringUtil.hasContent(selectData)){ + intent.putExtra("data", selectData); + } + startActivityForResult(intent, 1015); + break; + case R.id.btn_submit: + save(); + break; + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable @org.jetbrains.annotations.Nullable Intent data) { + if (resultCode == Activity.RESULT_OK) { + if (requestCode == 1015) {//选择应用返回 + if (data == null) { + ToastUtil.centered(getContext(), "选择应用错误!"); + return; + } + selectData = data.getStringExtra("selectData"); + Type type = new TypeToken>() { + }.getType(); + try { + Map selectValues = new Gson().fromJson(selectData, type); + if (selectValues==null){ + ToastUtil.centered(getContext(),"Type conversion exception"); + return; + } + if (selectValue!=null){ + selectValue.clear(); + } + selectValue = selectValues; + Set strings = selectValue.keySet(); + StringBuilder builder = new StringBuilder(); + String sp = ""; + for (String key : strings) { + builder.append(sp); + String[] strings1 = selectValue.get(key); + builder.append(strings1[0]); + builder.append("("); + builder.append(strings1[1]); + builder.append(")"); + sp = ";"; + } + viewBinding.tvSelectApp.setText(builder.toString()); + }catch (Exception e){ + e.printStackTrace(); + ToastUtil.centered(getContext(),"错误:"+e.getMessage()); + } + } +// if (requestCode == 1016) {//选择角色返回 +// if (data == null) { +// ToastUtil.centered(getContext(), "选择角色错误!"); +// return; +// } +// roleId = data.getStringExtra("roleId"); +// String appName = data.getStringExtra("roleName"); +// viewBinding.tvSelectJs.setText(appName); +// } + } + super.onActivityResult(requestCode, resultCode, data); + } + + private void isExit() { + String reason = getEditText(viewBinding.editReason); + String selectApp ="",phone=""; + if (StringUtil.isNullOrEmpty(data)){ + selectApp = getTextString(viewBinding.tvSelectApp); + phone = getEditText(viewBinding.editPhone); + } + if (!StringUtil.isNullOrEmptyAll(phone, reason, selectApp)) { + showNotSaveDialog(); + return; + } + finish(); + } + + private void save() { + String selectApp = getTextString(viewBinding.tvSelectApp); + if (StringUtil.isNullOrEmpty(selectApp)) { + ToastUtil.centered(getContext(), "请选择申请应用!"); + return; + } + String phone = getEditText(viewBinding.editPhone); +// if (StringUtil.isNullOrEmpty(phone)) { +// ToastUtil.centered(getContext(), "请输入联系电话!"); +// return; +// } + String reason = getEditText(viewBinding.editReason); + if (StringUtil.isNullOrEmpty(reason)) { + ToastUtil.centered(getContext(), "请输入原因!"); + return; + } + baseShowDialog("正在提交请稍后..."); + List> requestData = new ArrayList<>(); + Set strings = selectValue.keySet(); + + Map param = new HashMap<>(); + param.put("contact", phone); + param.put("reason", reason); + param.put("opType", getTextString(viewBinding.spSpinner)); + for (String key : strings) { + String[] strings1 = selectValue.get(key); + Map param1 = new HashMap<>(param); + param1.put("appId", key); + param1.put("appName", strings1[0]); + param1.put("appRole", strings1[1]); + requestData.add(param1); + } + MediaType mediaType = MediaType.Companion.parse("application/json;charset=utf-8"); + RequestBody stringBody = RequestBody.Companion.create(new Gson().toJson(requestData), mediaType); + + Map headMap = new HashMap<>(1); + headMap.put("app-yysq-token", RuanseeApplication.getAppCache().getApply_token()); + ApiModel.request(RetrofitService.getBaseInstance().applyPost(ApplyForMainActivity.BASE_URL + "apply/save", headMap, stringBody), + new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(TAG, msg); + baseDismissDialog(); + ToastUtil.centered(getContext(), msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + baseDismissDialog(); + baseDismissDialog(); + LogUtils.w(TAG, result.toString()); + JsonElement code = result.get("code"); + if (code == null) { + ToastUtil.centered(getContext(), result.get("msg").toString()); + return; + } + String s = code.toString(); + if ("200".equals(s)) { + ToastUtil.centered(getContext(), "操作成功!"); + finish(); + return; + } + ToastUtil.centered(getContext(), result.get("msg").toString()); + } + }); + } + + private void showNotSaveDialog() { + new AlertDialog.Builder(getContext()) + .setTitle("温馨提示") + .setMessage("您当前页面输入的内容未保存,退出后将清空页面数据,您是否坚持退出?") + .setNegativeButton("坚持退出", (dialog, which) -> { + dialog.dismiss(); + finish(); + }) + .setPositiveButton("取消", (dialog, which) -> dialog.dismiss()) + .create().show(); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + isExit(); + return false; + } + return super.onKeyDown(keyCode, event); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/MyApplyForActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/MyApplyForActivity.java new file mode 100644 index 0000000..d1f6bd4 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/MyApplyForActivity.java @@ -0,0 +1,75 @@ +package com.ycgis.macall.personalcenter.v.activity.applyfo; + + +import android.os.Bundle; +import android.view.View; + +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.base.BaseViewBindFragment; +import com.rs.macall.androidx.basemodel.base.ViewBindFragmentAdapter; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.ycgis.macall.personalcenter.databinding.ActivityMyApplyForBinding; +import com.ycgis.macall.personalcenter.v.adapter.InitiateRecordAdapter; +import com.ycgis.macall.personalcenter.v.fragment.ApplyOkFragment; +import com.ycgis.macall.personalcenter.v.fragment.ApplyRecordFragment; + +import java.util.ArrayList; +import java.util.List; + +/** + * 我的申请 + */ +public class MyApplyForActivity extends BaseViewBindActivity { + private InitiateRecordAdapter adapter; + private int page; + private final int pageSize = 10; + private int total; + private int refreshType; + + @Override + protected ActivityMyApplyForBinding getViewBinding() { + return ActivityMyApplyForBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + viewBinding.contentTitle.setText("我的申请"); + viewBinding.titleleft.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + finish(); + } + }); + + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void start() { + List dataList = new ArrayList<>(); + dataList.add(new ApplyRecordFragment()); + dataList.add(new ApplyOkFragment()); + ViewBindFragmentAdapter adapter = new ViewBindFragmentAdapter(getSupportFragmentManager(),dataList); + viewBinding.vpPage.setAdapter(adapter); +// viewBinding.vpPage.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){ +// @Override +// public void onPageScrollStateChanged(int state) { +// if (state == 2){ +// int currentItem = viewBinding.vpPage.getCurrentItem(); +// skip(currentItem); +// } +// } +// }); + viewBinding.tabLayout.setViewPager(viewBinding.vpPage,new String[]{"历史申请","申请通过"}); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/SelectSystemActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/SelectSystemActivity.java new file mode 100644 index 0000000..571212d --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/SelectSystemActivity.java @@ -0,0 +1,384 @@ +package com.ycgis.macall.personalcenter.v.activity.applyfo; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.view.inputmethod.EditorInfo; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.bigkoo.pickerview.builder.OptionsPickerBuilder; +import com.bigkoo.pickerview.listener.OnOptionsSelectListener; +import com.bigkoo.pickerview.view.OptionsPickerView; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.decoration.MyDividerItemDecoration; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.listener.OnLoadMoreListener; +import com.scwang.smart.refresh.layout.listener.OnRefreshListener; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivitySelectSystemBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.ApplyAppBean; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.m.adapterbean.SelectRoleBean; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.CommonCompositeManage; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.v.adapter.SelectSystemAdapter; + +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * 选择应用和角色 + */ +public class SelectSystemActivity extends BaseViewBindActivity { + private SelectSystemAdapter appAdapter; + private String selectData; + private int pageNum, pageSize = 10, totalCount; + private int refreshType = 0; + + @Override + protected ActivitySelectSystemBinding getViewBinding() { + return ActivitySelectSystemBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + LinearLayoutManager manager = new LinearLayoutManager(getContext()); + manager.setOrientation(LinearLayoutManager.VERTICAL); + viewBinding.rvAppList.setLayoutManager(manager); + MyDividerItemDecoration myDividerItemDecoration = new MyDividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL, 10); + myDividerItemDecoration.setOnMarginListener(new MyDividerItemDecoration.OnMarginListener() { + @Override + public int onLeft(int itemViewType, int Pointer) { + if (itemViewType == 1) { + return 15; + } else { + return 0; + } + } + }); + viewBinding.rvAppList.addItemDecoration(myDividerItemDecoration); +// viewBinding.search.editQuery.setImeOptions(EditorInfo.IME_ACTION_SEARCH); + SmartRefreshLayoutHelp.setPullDownToRefresh(getContext(), viewBinding.srlRefresh); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + selectData = getIntent().getStringExtra("data"); + } + + @Override + protected void start() { + viewBinding.leftImage.setImageDrawable(getDrawables(R.drawable.back_cliener)); + viewBinding.rightText.setText("确定"); +// goneView(viewBinding.search.getRoot()); + viewBinding.contentTitle.setText("选择应用和角色"); + setViewOnClickListener(viewBinding.titleright); + setViewOnClickListener(viewBinding.titleleft); +// queryEvent(); + refreshEvent(); + viewBinding.srlRefresh.autoRefresh(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + CommonCompositeManage.getInstance().unDisposable("getSqyyList"); + } + + + private void refreshEvent() { + viewBinding.srlRefresh.setOnRefreshListener(new OnRefreshListener() { + @Override + public void onRefresh(@NonNull @NotNull RefreshLayout refreshLayout) { + pageNum = 1; + refreshType = 1; + viewBinding.srlRefresh.resetNoMoreData(); + getAppData(); + } + }); + viewBinding.srlRefresh.setOnLoadMoreListener(new OnLoadMoreListener() { + @Override + public void onLoadMore(@NonNull @NotNull RefreshLayout refreshLayout) { + if (pageNum * pageSize >= totalCount) { + viewBinding.srlRefresh.finishLoadMoreWithNoMoreData(); + return; + } + pageNum++; + refreshType = 2; + getAppData(); + } + }); + } + + @Override + protected void bindViewClick(View v) { + if (v.getId() == R.id.titleleft) { + finish(); + } else if (v.getId() == R.id.titleright) { + submit(); + } + } + + private void submit() { + if (appAdapter == null) { + return; + } + if (appAdapter.getData() == null || appAdapter.getItemCount() <= 0) return; + Map param = new HashMap<>(); + for (BaseBean bean : appAdapter.getData()) { + if (bean instanceof SelectRoleBean) { + SelectRoleBean bean1 = (SelectRoleBean) bean; + String[] strings = {bean1.getAppName(), bean1.getName()}; + param.put(bean1.getAppId(), strings); + } + } + if (param.isEmpty()) { + ToastUtil.centered(getContext(), "请选择要申请的应用和角色"); + return; + } + Intent intent = new Intent(); +// intent.putExtra("roleId", String.valueOf(bean1.getId())); + intent.putExtra("selectData", new Gson().toJson(param)); + setResult(Activity.RESULT_OK, intent); + finish(); + } + + private void getAppData() { + Map headMap = new HashMap<>(1); + headMap.put("app-yysq-token", RuanseeApplication.getAppCache().getApply_token()); + ApiModel.request(RetrofitService.getBaseInstance().applyGet(ApplyForMainActivity.BASE_URL + "app/alllist", headMap, new HashMap<>()), + new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + viewBinding.srlRefresh.finishRefresh(); + LogUtils.e(TAG, msg); + List dataList = new ArrayList<>(); + BaseBean baseBean = new BaseBean() { + }; + baseBean.setBaseType(-1); + baseBean.setBaseMessage(msg); + dataList.add(baseBean); + initAppData(dataList); + } + + @Override + public void onRequestSuccess(JsonObject result) { + LogUtils.w(TAG, result.toString()); + viewBinding.srlRefresh.finishRefresh(); + try { + ApplyAppBean applyAppBean = new Gson().fromJson(result.toString(), ApplyAppBean.class); + if (!applyAppBean.isSuccess()) { + List dataList = new ArrayList<>(); + BaseBean baseBean = new BaseBean() { + }; + baseBean.setBaseType(-1); + baseBean.setBaseMessage(applyAppBean.getMsg()); + dataList.add(baseBean); + initAppData(dataList); + return; + } + List data = applyAppBean.getData(); + handlerData(data); + } catch (Exception e) { + e.printStackTrace(); + List dataList = new ArrayList<>(); + BaseBean baseBean = new BaseBean() { + }; + baseBean.setBaseType(-1); + baseBean.setBaseMessage(e.getMessage()); + dataList.add(baseBean); + initAppData(dataList); + } + } + }); + } + + private void handlerData(List data) { + Map stringMap = null; + if (StringUtil.hasContent(selectData)) { + Type type = new TypeToken>() { + }.getType(); + stringMap = new Gson().fromJson(StringUtil.toJsonParaphrase(selectData), type); + } + List dataList = new ArrayList<>(); + if (data == null || data.isEmpty()) { + BaseBean baseBean = new BaseBean() { + }; + baseBean.setBaseType(0); + baseBean.setBaseMessage("暂无应用"); + dataList.add(baseBean); + } else { + for (ApplyAppBean.DataBean b : data) { + b.setBaseType(1); + dataList.add(b); + } + if (stringMap!=null){ + Set strings = stringMap.keySet(); + for (String key : strings) { + String[] strings1 = stringMap.get(key); + for (int i = 0; i < dataList.size(); i++) { + BaseBean baseBean = dataList.get(i); + if (baseBean instanceof ApplyAppBean.DataBean){ + ApplyAppBean.DataBean bean = (ApplyAppBean.DataBean) baseBean; + int selectId = TypConversion.strToInt(key); + if (bean.getId() == selectId) { + bean.setSelect(true); + SelectRoleBean bean1 = new SelectRoleBean(); + bean1.setBaseType(3); + bean1.setName(strings1[1]); + bean1.setAppId(key); + bean1.setAppName(strings1[0]); + dataList.add(i+1,bean1); + } + } + } + } + } + } + initAppData(dataList); + } + + private void showItemSelectDialog(List list) { + OptionsPickerView build = new OptionsPickerBuilder(getContext(), new OnOptionsSelectListener() { + @Override + public void onOptionsSelect(int options1, int options2, int options3, View v) { + Object o = list.get(options1); + BaseBean dataItem = appAdapter.getDataItem(selectPointer); + if (dataItem instanceof ApplyAppBean.DataBean) { + ApplyAppBean.DataBean bean = (ApplyAppBean.DataBean) dataItem; + if (selectPointer < appAdapter.getItemCount() - 1) { + BaseBean dataItem1 = appAdapter.getDataItem(selectPointer + 1); + if (dataItem1 instanceof SelectRoleBean) { + SelectRoleBean bean1 = (SelectRoleBean) dataItem1; + bean1.setName(o.toString()); + bean1.setAppId(String.valueOf(bean.getId())); + bean1.setAppName(bean.getName()); + appAdapter.notifyItemChanged(selectPointer + 1, 6); + } else { + SelectRoleBean bean1 = new SelectRoleBean(); + bean1.setBaseType(3); + bean1.setName(o.toString()); + bean1.setAppId(String.valueOf(bean.getId())); + bean1.setAppName(bean.getName()); + appAdapter.addItem(selectPointer + 1, bean1); + } + } else if (selectPointer == appAdapter.getItemCount() - 1) { + SelectRoleBean bean1 = new SelectRoleBean(); + bean1.setBaseType(3); + bean1.setName(o.toString()); + bean1.setAppId(String.valueOf(bean.getId())); + bean1.setAppName(bean.getName()); + appAdapter.addItem(selectPointer + 1, bean1); + + } + bean.setSelect(true); + appAdapter.notifyItemChanged(selectPointer, 1); + } + } + }).setCancelText("取消") + .setCancelColor(getColors(R.color.colorGreen6)) + .setSubmitText("确定") + .setSubmitColor(getColors(R.color.colorBluen7)) + .setContentTextSize(16) + .setTitleText("请选择角色") + .setTitleSize(16) + .setTitleColor(getColors(R.color.colorBluen8)) + .setSubCalSize(14) + .build(); + build.setPicker(list); + build.show(); + } + + private int selectPointer = 0; + + // + private void initAppData(List dataList) { + if (appAdapter == null) { + appAdapter = new SelectSystemAdapter(getContext(), dataList); + viewBinding.rvAppList.setAdapter(appAdapter); + appAdapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + BaseBean item = appAdapter.getDataItem(pointer); + if (item instanceof ApplyAppBean.DataBean) { + ApplyAppBean.DataBean dataItem = (ApplyAppBean.DataBean) item; + if (dataItem.getBaseType() != 1) return; + if (dataItem.isSelect()){ + dataItem.setSelect(false); + appAdapter.notifyItemChanged(pointer,1); + List data = appAdapter.getData(); + for (int i =0;i roles = dataItem.getRoles(); + if (roles != null) { + List list = new ArrayList<>(); + list.addAll(roles); + selectPointer = pointer; + showItemSelectDialog(list); + } + } + if (item instanceof SelectRoleBean) { + SelectRoleBean dataItem = (SelectRoleBean) item; + if (dataItem.getBaseType() != 2) return; + int sygxz = -1; + for (int i = 0; i < appAdapter.getItemCount(); i++) { + BaseBean dataItem1 = appAdapter.getDataItem(i); + if (dataItem1 instanceof SelectRoleBean) { + SelectRoleBean bean = (SelectRoleBean) dataItem1; + if (bean.isSelect()) { + sygxz = i; + bean.setSelect(false); + break; + } + } + } + if (sygxz != -1) { + appAdapter.notifyItemChanged(sygxz, 1); + } + dataItem.setSelect(true); + appAdapter.notifyItemChanged(pointer, 1); + } + } + }); + } else { + appAdapter.upData(dataList); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/ToBeReviewedActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/ToBeReviewedActivity.java new file mode 100644 index 0000000..d1c90a3 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/applyfo/ToBeReviewedActivity.java @@ -0,0 +1,541 @@ +package com.ycgis.macall.personalcenter.v.activity.applyfo; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.LinearLayoutManager; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.EditText; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.BaseRecycleBtnClickListener; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.decoration.MyDividerItemDecoration; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityToBeReviewedBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.ApplyBean; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.callback.OnAdapterLongClickListener; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.v.adapter.InitiateRecordAdapter; + +import org.jetbrains.annotations.NotNull; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import okhttp3.MediaType; +import okhttp3.RequestBody; + +/** + * 待审核 + */ +public class ToBeReviewedActivity extends BaseViewBindActivity { + private InitiateRecordAdapter adapter; + private int page; + private final int pageSize = 10; + private int total; + private int refreshType; + private int operatingType; + + @Override + protected ActivityToBeReviewedBinding getViewBinding() { + return ActivityToBeReviewedBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + viewBinding.titleleft.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + finish(); + } + }); + LinearLayoutManager manager = new LinearLayoutManager(getContext()); + manager.setOrientation(LinearLayoutManager.VERTICAL); + viewBinding.rvAppList.setLayoutManager(manager); + SmartRefreshLayoutHelp.setPullDownToRefresh(getContext(), viewBinding.srlRefresh); + setViewOnClickListener(viewBinding.btnCancel); + setViewOnClickListener(viewBinding.btnSubmit); + } + + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + if (savedInstanceState == null) { + operatingType = getIntent().getIntExtra("operatingType", 1); + savePageCacheData("operatingType", operatingType); + } else { + operatingType = savedInstanceState.getInt("operatingType"); + } + } + + @Override + protected void bindViewClick(View v) { + if (v.getId() == R.id.btn_cancel) { + cleanMoreOperation(); + } else if (v.getId() == R.id.btn_submit) { + //显示批量提交弹框 + showMoreOperationDialog(); + } + } + + private void cleanMoreOperation(){ + goneView(viewBinding.llMoreOperation); + List data = adapter.getData(); + for (int i = 0; i < data.size(); i++) { + ApplyBean bean = (ApplyBean) data.get(i); + bean.setMore(false); + bean.setSel(false); + adapter.notifyItemChanged(i, 5); + } + } + + private void showMoreOperationDialog() { + Dialog dialog = new AlertDialog.Builder(getContext()) + .setView(getLayoutInflater().inflate(R.layout.dialog_batch_audit, null, false)) + .create(); + dialog.show(); + EditText editText = dialog.findViewById(R.id.edit_audit_view); + dialog.findViewById(R.id.btn_reject).setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + submit(false,getEditText(editText)); + dialog.dismiss(); + } + }); + dialog.findViewById(R.id.btn_pass).setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + submit(true,getEditText(editText)); + dialog.dismiss(); + } + }); + } + + /** + * 不通过为0 通过为 1 + * + * @param isPass 是否通过 + */ + private void submit(boolean isPass, String opinion) { + baseShowDialog("正在提交,请稍后..."); + List applyId = new ArrayList<>(); + List data = adapter.getData(); + for (int i = 0; i < data.size(); i++) { + ApplyBean bean = (ApplyBean) data.get(i); + if (bean.isSel()){ + applyId.add(bean.getId()); + } + } + + Map param = new HashMap<>(); + param.put("applyId", ""); + param.put("applyIds", applyId.toArray()); + param.put("auditStatus", String.valueOf(isPass ? 1 : 0)); + param.put("opinion", opinion); + baseShowDialog("正在查询审核记录,请稍后..."); + Map headMap = new HashMap<>(1); + headMap.put("app-yysq-token", RuanseeApplication.getAppCache().getApply_token()); + MediaType mediaType = MediaType.Companion.parse("application/json;charset=utf-8"); + RequestBody stringBody = RequestBody.Companion.create(new Gson().toJson(param), mediaType); + ApiModel.request(RetrofitService.getBaseInstance().applyPost(ApplyForMainActivity.BASE_URL + "audit/batchadd", headMap, stringBody), new BaseRequestCallback() { + + @Override + public void onRequestFailure(String msg) { + Log.e(TAG, msg); + baseDismissDialog(); + ToastUtil.centered(getContext(), msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + Log.w(TAG, result.toString()); + baseDismissDialog(); + //{"msg":"操作成功","code":200} + try { + JSONObject object = new JSONObject(result.toString()); + ToastUtil.centered(getContext(), TypConversion.getJsonStr(object,"msg")); + int code = TypConversion.getJsonInt(object, "code", -1); + if (code != 200) { + ToastUtil.centered(getContext(),TypConversion.getJsonStr(object,"msg")); + return; + } + cleanMoreOperation(); + viewBinding.srlRefresh.autoRefresh(); + } catch (JSONException e) { + e.printStackTrace(); + ToastUtil.centered(getContext(), "msg"); + } + } + }); + } + + @Override + protected void start() { + if (operatingType == 1) { + viewBinding.contentTitle.setText("审核记录"); + viewBinding.rvAppList.addItemDecoration(new MyDividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL)); + } else if (operatingType == 2) { + viewBinding.contentTitle.setText("我的审核"); + } else if (operatingType == 3) { + viewBinding.contentTitle.setText("审核记录"); + viewBinding.rvAppList.addItemDecoration(new MyDividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL)); + } + viewBinding.srlRefresh.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull @NotNull RefreshLayout refreshLayout) { + if (page * pageSize >= total) { + viewBinding.srlRefresh.finishLoadMoreWithNoMoreData(); + return; + } + page++; + refreshType = 2; + if (operatingType == 2) { + getAuditList(); + } else if (operatingType == 3) { + getAuditRecord(); + } + } + + @Override + public void onRefresh(@NonNull @NotNull RefreshLayout refreshLayout) { + viewBinding.srlRefresh.resetNoMoreData(); + page = 1; +// getData(); + refreshType = 1; + if (operatingType == 2) { + getAuditList(); + } else if (operatingType == 3) { + getAuditRecord(); + } + } + }); + viewBinding.srlRefresh.autoRefresh(); + } + + private void getErrorList(int type, String msg) { + List baseBeans = new ArrayList<>(); + BaseBean baseBean = new BaseBean() { + }; + baseBean.setBaseType(type); + baseBean.setBaseMessage(msg); + baseBeans.add(baseBean); + initData(baseBeans); + } + + private void getAuditRecord() { + Map param = new HashMap<>(); + param.put("pageNum", page); + param.put("pageSize", pageSize); + Map headMap = new HashMap<>(1); + headMap.put("app-yysq-token", RuanseeApplication.getAppCache().getApply_token()); + ApiModel.request(RetrofitService.getBaseInstance().applyGet(ApplyForMainActivity.BASE_URL + "audit/history", headMap, param), new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(TAG, msg); + stopRefreshAnim(-1, msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + LogUtils.w(TAG, result.toString()); + try { + JSONObject object = new JSONObject(result.toString()); + int code = TypConversion.getJsonInt(object, "code", -1); + if (code != 200) { + getErrorList(-1, TypConversion.getJsonStr(object, "msg")); + return; + } + total = TypConversion.getJsonInt(object, "total", 0); + JSONArray rows = TypConversion.getJSONArray(object, "rows"); + if (rows == null) { + if (refreshType == 1) { + refreshType = 0; + viewBinding.srlRefresh.finishRefresh(); + if (operatingType == 2) { + getErrorList(0, "暂无审核!"); + } else if (operatingType == 3) { + getErrorList(0, "暂无审核记录!"); + } + } else { + viewBinding.srlRefresh.finishLoadMore(); + refreshType = 0; + if (operatingType == 2) { + ToastUtil.centered(getContext(), "暂无审核!"); + } else if (operatingType == 3) { + ToastUtil.centered(getContext(), "暂无审核记录!"); + } + } + return; + } + + List dataList = new ArrayList<>(); + for (int i = 0; i < rows.length(); i++) { + JSONObject jsonObject = TypConversion.getJSONObject(rows, i); + if (jsonObject == null) continue; + int status = TypConversion.getJsonInt(jsonObject, "status", 11); + if (status == 0) continue; + ApplyBean bean = new ApplyBean(); + bean.setBaseType(operatingType); + bean.setId(TypConversion.getJsonStr(jsonObject, "id")); + bean.setSysName(TypConversion.getJsonStr(jsonObject, "appName")); + bean.setRoleName(TypConversion.getJsonStr(jsonObject, "appRole")); + bean.setPhone(TypConversion.getJsonStr(jsonObject, "contact")); + bean.setApplyReason(TypConversion.getJsonStr(jsonObject, "reason")); + bean.setSysId(TypConversion.getJsonStr(jsonObject, "appId")); + bean.setName(TypConversion.getJsonStr(jsonObject, "nickName")); + bean.setCode(TypConversion.getJsonStr(jsonObject, "userName")); + bean.setDeptCode(TypConversion.getJsonStr(jsonObject, "deptId")); + bean.setDeptName(TypConversion.getJsonStr(jsonObject, "deptName")); + bean.setIdCordNum(TypConversion.getJsonStr(jsonObject, "idcard")); + bean.setState(TypConversion.getJsonInt(jsonObject, "status", 11)); + bean.setNode(TypConversion.getJsonStr(jsonObject, "appRole")); + bean.setTime(TypConversion.getJsonStr(jsonObject, "opTime")); + bean.setUserId(TypConversion.getJsonStr(jsonObject, "userId")); + String opType = TypConversion.getJsonStr(jsonObject, "opType"); + bean.setType("申请".equals(opType) ? 1 : 2); + dataList.add(bean); + } + if (refreshType == 1) { + refreshType = 0; + viewBinding.srlRefresh.finishRefresh(); + if (dataList.isEmpty()) { + if (operatingType == 2) { + getErrorList(0, "暂无审核!"); + } else if (operatingType == 3) { + getErrorList(0, "暂无审核记录!"); + } + return; + } + initData(dataList); + } else { + viewBinding.srlRefresh.finishLoadMore(); + refreshType = 0; + if (dataList.isEmpty()) { + if (operatingType == 2) { + ToastUtil.centered(getContext(), "暂无审核!"); + } else if (operatingType == 3) { + ToastUtil.centered(getContext(), "暂无审核记录!"); + } + return; + } + adapter.addData(dataList); + } + if (page * pageSize >= total) { + viewBinding.srlRefresh.finishLoadMoreWithNoMoreData(); + } + } catch (JSONException e) { + e.printStackTrace(); + stopRefreshAnim(-1, e.getMessage()); + } + } + }); + } + + private void getAuditList() { + Map param = new HashMap<>(); + param.put("pageNum", page); + param.put("pageSize", pageSize); + Map headMap = new HashMap<>(1); + headMap.put("app-yysq-token", RuanseeApplication.getAppCache().getApply_token()); + ApiModel.request(RetrofitService.getBaseInstance().applyGet(ApplyForMainActivity.BASE_URL + "audit/my", headMap, param), new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(TAG, msg); + stopRefreshAnim(-1, msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + LogUtils.w(TAG, result.toString()); + try { + JSONObject object = new JSONObject(result.toString()); + int code = TypConversion.getJsonInt(object, "code", -1); + if (code != 200) { + getErrorList(-1, TypConversion.getJsonStr(object, "msg")); + return; + } + total = TypConversion.getJsonInt(object, "total", 0); + JSONArray rows = TypConversion.getJSONArray(object, "rows"); + if (rows == null) { + stopRefreshAnim(0, "暂无审核!"); + return; + } + + List dataList = new ArrayList<>(); + for (int i = 0; i < rows.length(); i++) { + JSONObject jsonObject = TypConversion.getJSONObject(rows, i); + if (jsonObject == null) continue; + int status = TypConversion.getJsonInt(jsonObject, "status", 11); + if (status == 0) continue; + ApplyBean bean = new ApplyBean(); + bean.setBaseType(operatingType); + bean.setId(TypConversion.getJsonStr(jsonObject, "id")); + bean.setSysName(TypConversion.getJsonStr(jsonObject, "appName")); + bean.setRoleName(TypConversion.getJsonStr(jsonObject, "appRole")); + bean.setName(TypConversion.getJsonStr(jsonObject, "nickName")); + bean.setCode(TypConversion.getJsonStr(jsonObject, "userName")); + bean.setDeptCode(TypConversion.getJsonStr(jsonObject, "deptId")); + bean.setDeptName(TypConversion.getJsonStr(jsonObject, "deptName")); + bean.setIdCordNum(TypConversion.getJsonStr(jsonObject, "idcard")); + bean.setApplyReason(TypConversion.getJsonStr(jsonObject, "reason")); + bean.setState(TypConversion.getJsonInt(jsonObject, "status", 11)); + bean.setNode(TypConversion.getJsonStr(jsonObject, "appRole")); + bean.setTime(TypConversion.getJsonStr(jsonObject, "opTime")); + bean.setUserId(TypConversion.getJsonStr(jsonObject, "userId")); + String opType = TypConversion.getJsonStr(jsonObject, "opType"); + bean.setType("申请".equals(opType) ? 1 : 2); + dataList.add(bean); + } + if (refreshType == 1) { + refreshType = 0; + viewBinding.srlRefresh.finishRefresh(); + if (dataList.isEmpty()) { + getErrorList(0, "暂无审核!"); + return; + } + initData(dataList); + } else { + viewBinding.srlRefresh.finishLoadMore(); + refreshType = 0; + if (dataList.isEmpty()) { + ToastUtil.centered(getContext(), "暂无审核!"); + return; + } + adapter.addData(dataList); + } + if (page * pageSize >= total) { + viewBinding.srlRefresh.finishLoadMoreWithNoMoreData(); + } + } catch (JSONException e) { + e.printStackTrace(); + stopRefreshAnim(-1, e.getMessage()); + } + } + }); + } + + private void stopRefreshAnim(int type, String msg) { + if (refreshType == 1) { + refreshType = 0; + viewBinding.srlRefresh.finishRefresh(); + getErrorList(type, msg); + } else { + viewBinding.srlRefresh.finishLoadMore(); + refreshType = 0; + ToastUtil.centered(getContext(), msg); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable @org.jetbrains.annotations.Nullable Intent data) { + if (requestCode == 1101 && resultCode == Activity.RESULT_OK) { + viewBinding.srlRefresh.autoRefresh(); + } + super.onActivityResult(requestCode, resultCode, data); + } + + private void updateMoreOperationText() { + List data = adapter.getData(); + int selCount = 0; + for (int i = 0; i < data.size(); i++) { + ApplyBean bean = (ApplyBean) data.get(i); + if (bean.isSel()) { + selCount++; + } + } + viewBinding.tvSelCount.setText("已选中" + selCount); + } + + private void initData(List dataList) { + viewBinding.srlRefresh.finishRefresh(); + if (adapter == null) { + adapter = new InitiateRecordAdapter(getContext(), dataList); + viewBinding.rvAppList.setAdapter(adapter); + Long interval = 1000l; + if (operatingType == 2){ + interval = 500l; + } + adapter.setListClickListener(new SimpleListClickListener(interval) { + @Override + public void onSingleClick(View v, int pointer) { + BaseBean dataItem = adapter.getDataItem(pointer); + if (dataItem instanceof ApplyBean) { + ApplyBean bean = (ApplyBean) dataItem; + if (operatingType == 2) { + if (bean.isMore()) { + bean.setSel(!bean.isSel()); + updateMoreOperationText(); + adapter.notifyItemChanged(pointer, 3); + return; + } + } + Intent intent = new Intent(getContext(), ApplyDetailsActivity.class); + intent.putExtra("data", new Gson().toJson(bean)); + intent.putExtra("operatingType", operatingType); + startActivityForResult(intent, 1101); + } + } + }); + if (operatingType == 2) { + adapter.setBtnClickListener(new BaseRecycleBtnClickListener() { + @Override + public void onSingleClick(View v, int position, int what, Object msg) { + updateMoreOperationText(); + } + }); + adapter.setLongClickListener(new OnAdapterLongClickListener(null, 0) { + @Override + protected void onLongClick(View v, BaseBean data, int position) { + //显示下方控件 + if (viewBinding.llMoreOperation.getVisibility() != View.VISIBLE) { + viewBinding.llMoreOperation.setVisibility(View.VISIBLE); + List data1 = adapter.getData(); + for (int i = 0; i < data1.size(); i++) { + ApplyBean bean = (ApplyBean) data1.get(i); + bean.setMore(true); + if (i == position) { + bean.setSel(true); + } + adapter.notifyItemChanged(i, 5); + } + updateMoreOperationText(); + } + } + }); + } + } else { + adapter.upData(dataList); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/travel/TravelAssistantActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/travel/TravelAssistantActivity.java new file mode 100644 index 0000000..8989a1f --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/travel/TravelAssistantActivity.java @@ -0,0 +1,336 @@ +package com.ycgis.macall.personalcenter.v.activity.travel; + +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.KeyEvent; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.widget.TextView; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.decoration.MyDividerItemDecoration; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityTravelAssistantBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.TravelCityBean; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.v.adapter.TravelAssistantAdapter; +import com.ycgis.macall.personalcenter.v.adapter.TravelSearchListAdapter; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +/** + * 差旅助手 + */ +public class TravelAssistantActivity extends BaseViewBindActivity { + private TravelAssistantAdapter historyAdapter, popularAdapter; + private TravelSearchListAdapter searchAdapter; + + @Override + protected ActivityTravelAssistantBinding getViewBinding() { + return ActivityTravelAssistantBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + GridLayoutManager manager1 = new GridLayoutManager(getContext(), 4); + GridLayoutManager manager2 = new GridLayoutManager(getContext(), 4); + viewBinding.travelRvHistory.setLayoutManager(manager1); + viewBinding.travelRvPopular.setLayoutManager(manager2); + viewBinding.travelRvApplist.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); + MyDividerItemDecoration myDividerItemDecoration = new MyDividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL); + myDividerItemDecoration.setBottom(true); + viewBinding.travelRvApplist.addItemDecoration(myDividerItemDecoration); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void start() { + viewBinding.travelTitle.contentTitle.setText("差旅助手"); + viewBinding.travelTitle.leftImage.setImageDrawable(getDrawable(R.drawable.back_cliener)); + viewBinding.travelTitle.titleleft.setOnClickListener(v -> finish()); + viewBinding.trvaelSearch.editQuery.setHint("搜索城市 如:北京/bj/beijing"); + viewBinding.trvaelSearch.editQuery.setImeOptions(EditorInfo.IME_ACTION_SEARCH); + viewBinding.trvaelSearch.btnClean.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + viewBinding.trvaelSearch.editQuery.setText(""); + goneView(viewBinding.travelRvApplist); + } + }); + viewBinding.trvaelSearch.editQuery.setOnEditorActionListener((v, actionId, event) -> { + if (actionId == EditorInfo.IME_ACTION_SEARCH) { + String searchWord = getEditText(viewBinding.trvaelSearch.editQuery); + baseShowDialog("正在搜索,请稍后..."); + searchApp(searchWord); + return true; + } + return false; + }); + + viewBinding.trvaelSearch.editQuery.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + if (s == null || StringUtil.isNullOrEmpty(s.toString())) { + goneView(viewBinding.trvaelSearch.btnClean); + return; + } + visibleView(viewBinding.trvaelSearch.btnClean); + } + }); + baseShowDialog("正在获取数据,请稍后..."); + getDataS(); + } + + private TravelCityBean getErrorBean(int type, String msg) { + TravelCityBean bean = new TravelCityBean(); + bean.setBaseType(type); + bean.setBaseMessage(msg); + return bean; + } + + private void searchApp(String searchWord) { + ApiModel.request(RetrofitService.getBaseInstance().getSearchCity(searchWord), new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(TAG, msg); + baseDismissDialog(); + ToastUtil.centered(getContext(), msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + //{"code":20041,"data":["北京"],"msg":""} + LogUtils.w(TAG, result.toString()); + baseDismissDialog(); + List dataList = new ArrayList<>(); + try { + JSONObject object = new JSONObject(result.toString()); + int code = TypConversion.getJsonInt(object, "code", -1); + if (code == 20041) { + JSONArray data = TypConversion.getJSONArray(object, "data"); + for (int i = 0; i < data.length(); i++) { + String string = data.getString(i); + TravelCityBean bean = new TravelCityBean(); + bean.setBaseType(1); + bean.setName(string); + dataList.add(bean); + } + if (dataList.isEmpty()) { + TravelCityBean errorBean = getErrorBean(0, "未搜索到该城市,请使用城市全称或全拼进行搜索。"); + dataList.add(errorBean); + } + initSearchList(dataList); + } else { + TravelCityBean errorBean = getErrorBean(-1, TypConversion.getJsonStr(object, "msg")); + dataList.add(errorBean); + initSearchList(dataList); + } + } catch (JSONException e) { + e.printStackTrace(); + TravelCityBean errorBean = getErrorBean(-1, e.getMessage()); + dataList.add(errorBean); + initSearchList(dataList); + } + } + }); + + } + + private void initSearchList(List dataList) { + visibleView(viewBinding.travelRvApplist); + if (searchAdapter == null) { + searchAdapter = new TravelSearchListAdapter(getContext(), dataList); + viewBinding.travelRvApplist.setAdapter(searchAdapter); + searchAdapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + TravelCityBean dataItem = searchAdapter.getDataItem(pointer); + if (dataItem.getBaseType() == 1) { + goneView(viewBinding.travelRvApplist); + handlerFootData(dataItem); + } + } + }); + } else { + searchAdapter.upData(dataList); + } + } + + private void getDataS() { + ApiModel.request("getCity", + RetrofitService.getBaseInstance().getPopularCity(RuanseeApplication.getUserData().getUserCode()), + new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + baseDismissDialog(); + LogUtils.e(TAG, msg); + List dataList = new ArrayList<>(); + dataList.add(getErrorBean(-1, msg)); + initPopularData(dataList); + initHistoryData(dataList); + } + + + @Override + public void onRequestSuccess(JsonObject result) { + baseDismissDialog(); + LogUtils.w(TAG, result.toString()); + try { + JSONObject object = new JSONObject(result.toString()); + int code = TypConversion.getJsonInt(object, "code", -200); + if (code == 20041) { + JSONObject data = TypConversion.getJSONObject(object, "data"); + if (data == null) { + return; + } + JSONArray footCity = TypConversion.getJSONArray(data, "footCity"); + List footCityList = new ArrayList<>(); + if (footCity == null) { + footCityList.add(getErrorBean(0, "暂无足迹数据")); + } else { + for (int i = 0; i < footCity.length(); i++) { + String string = footCity.getString(i); + if (string == null) continue; + TravelCityBean bean = new TravelCityBean(); + bean.setBaseType(1); + bean.setName(string); + footCityList.add(bean); + } + } + initHistoryData(footCityList); + JSONArray popularCity = TypConversion.getJSONArray(data, "popularCity"); + List popularCityList = new ArrayList<>(); + if (popularCity == null) { + popularCityList.add(getErrorBean(0, "暂无热门城市推荐")); + } else { + for (int i = 0; i < popularCity.length(); i++) { + String string = popularCity.getString(i); + if (string == null) continue; + TravelCityBean bean = new TravelCityBean(); + bean.setBaseType(1); + bean.setName(string); + popularCityList.add(bean); + } + } + initPopularData(popularCityList); + } else { + List dataList = new ArrayList<>(); + dataList.add(getErrorBean(-1, TypConversion.getJsonStr(object, "msg"))); + initPopularData(dataList); + initHistoryData(dataList); + } + } catch (JSONException e) { + e.printStackTrace(); + List dataList = new ArrayList<>(); + dataList.add(getErrorBean(-1, e.getMessage())); + initPopularData(dataList); + initHistoryData(dataList); + } + } + }); + } + + private void initPopularData(List dataList) { + if (popularAdapter == null) { + popularAdapter = new TravelAssistantAdapter(getContext(), dataList); + viewBinding.travelRvPopular.setAdapter(popularAdapter); + popularAdapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + TravelCityBean dataItem = popularAdapter.getDataItem(pointer); + if (dataItem.getBaseType() == 1) { + handlerFootData(dataItem); + } + } + }); + } else { + popularAdapter.upData(dataList); + } + } + + private void initHistoryData(List dataList) { + if (historyAdapter == null) { + historyAdapter = new TravelAssistantAdapter(getContext(), dataList); + viewBinding.travelRvHistory.setAdapter(historyAdapter); + historyAdapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + TravelCityBean dataItem = popularAdapter.getDataItem(pointer); + if (dataItem.getBaseType() == 1) { + handlerFootData(dataItem); + } + } + }); + } else { + historyAdapter.upData(dataList); + } + } + + private void handlerFootData(TravelCityBean bean) { + Intent intent = new Intent(getContext(), TravelDetailsActivity.class); + intent.putExtra("cityName", bean.getName()); + intent.putExtra("level", "1"); + startActivity(intent); + if (historyAdapter == null) return; + List data = historyAdapter.getData(); + if (data == null) return; + + int index = -1; + for (int i = 0; i < data.size(); i++) { + TravelCityBean beans = data.get(i); + if (beans.getName().endsWith(bean.getName())) { + index = i; + break; + } + } + if (index>-1){ + historyAdapter.removeItem(index); + }else { + if (historyAdapter.getItemCount()>=12){ + historyAdapter.removeItem(data.size() - 1); + } + } + historyAdapter.addItem(0, bean); + + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/travel/TravelDetailsActivity.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/travel/TravelDetailsActivity.java new file mode 100644 index 0000000..afab357 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/activity/travel/TravelDetailsActivity.java @@ -0,0 +1,143 @@ +package com.ycgis.macall.personalcenter.v.activity.travel; + + +import android.content.Intent; +import android.os.Bundle; + +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ActivityTravelDetailsBinding; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.CommonComposite; +import com.ycgis.macall.personalcenter.p.request.CommonCompositeManage; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; + +import org.json.JSONException; +import org.json.JSONObject; + +public class TravelDetailsActivity extends BaseViewBindActivity { + private String cityName; + private String level; + + @Override + protected ActivityTravelDetailsBinding getViewBinding() { + return ActivityTravelDetailsBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + if (savedInstanceState == null) { + Intent intent = getIntent(); + cityName = intent.getStringExtra("cityName"); + level = intent.getStringExtra("level"); + } + } + + @Override + protected void start() { + viewBinding.travelDetalisTitle.contentTitle.setText("一般人员报销标准"); + viewBinding.travelDetalisTitle.leftImage.setImageDrawable(getDrawable(R.drawable.back_cliener)); + viewBinding.travelDetalisTitle.titleleft.setOnClickListener(v -> finish()); + baseShowDialog("正在加载请稍后..."); + viewBinding.travelTvCityName.setText(String.format("%s差旅报销标准", cityName)); + getData(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + CommonCompositeManage.getInstance().unDisposable("getCitystandard"); + } + + private void getData() { + ApiModel.request("getCitystandard", + RetrofitService.getBaseInstance().getMoneyCity(RuanseeApplication.getUserData().getUserCode(), cityName, level) + , new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + baseDismissDialog(); + LogUtils.e(TAG, msg); + ToastUtil.centered(getContext(),msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + baseDismissDialog(); + LogUtils.w(TAG, result.toString()); + //{"code":20041,"data":{"carfare":"火车:软席(软座、软卧),高铁/动车一等座,全列软席列车一等软座;轮船:二等舱;飞机:经济舱","content":"600元/人天","taxi":"80元/人天","wages":"100元/人天"},"msg":""} + try { + JSONObject object = new JSONObject(result.toString()); + int code = TypConversion.getJsonInt(object, "code", -1); + if (code == 20041) { + JSONObject data = TypConversion.getJSONObject(object, "data"); + String carfare = TypConversion.getJsonStr(data, "carfare"); + String[] split = carfare.split(";"); + for (int i = 0; i < split.length; i++) { + String[] split1 = split[i].split(":"); + if (i == 0) { + String[] split2 = split1[1].split(","); + String sp = ""; + StringBuilder builder = new StringBuilder(); + for (int j = 0; j < split2.length; j++) { + builder.append(sp); + builder.append(split2[j]); + sp="\n"; + } + viewBinding.travelTvTrain.setText(StringUtil.get(builder.toString(),"暂无")); + continue; + } + if (i == 1){ + viewBinding.travelTvShips.setText(StringUtil.get(split1[1],"暂无")); + } + if (i == 2){ + viewBinding.travelTvAircraft.setText(StringUtil.get(split1[1],"暂无")); + } + } + String content1 = TypConversion.getJsonStr(data, "content"); + String content = "暂无"; + if (content1.contains(";")){ + String[] split1 = content1.split(";"); + String sp = ""; + StringBuilder builder = new StringBuilder(); + for (int j = 0; j { + + public AppGuideDetailsAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 0||viewType == -1){ + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_error,parent,false); + return new ErrorViewHolder(view); + } + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_operation_type,parent,false); + return new SimpleViewHolder(view).findViewById(R.id.ic_img).findViewById(R.id.tv_op_name).findViewById(R.id.iv_play); + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder){ + ErrorViewHolder holder = (ErrorViewHolder)viewHolder; + if (getDataItem(position).getBaseType() == 0){ + holder.setEmpty(getDataItem(position).getBaseMessage()); + }else { + holder.setError(getDataItem(position).getBaseMessage()); + } + } + if (viewHolder instanceof BaseRecyclerAdapter.SimpleViewHolder){ + AppGuideDetailsBean dataItem = getDataItem(position); + SimpleViewHolder holder = (SimpleViewHolder) viewHolder; + ImageView ic_img = holder.getView(R.id.ic_img, ImageView.class); + ImageView iv_play = holder.getView(R.id.iv_play, ImageView.class); + TextView tv_name = holder.getView(R.id.tv_op_name, TextView.class); + String filePath = dataItem.getFilePath(); + int i = filePath.lastIndexOf("/"); + String substring = filePath.substring(i+1); + tv_name.setVisibility(View.VISIBLE); + tv_name.setText(substring); + if (dataItem.getType() == 1){ + //图片 + setImg(ic_img,getDataItem(position).getFilePath()); + iv_play.setVisibility(View.GONE); + }else if (dataItem.getType() ==2){ + //视频 + loadVideoScreenshot(context,filePath,ic_img); + iv_play.setVisibility(View.VISIBLE); + }else { + //文件 + iv_play.setVisibility(View.GONE); + if (wd.contains(substring)){ + ic_img.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.fileselect_img_doc)); + }else if (ex.contains(substring)){ + ic_img.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.fileselect_img_xls)); + }else if (zip.contains(substring)){ + ic_img.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.fileselect_img_zip)); + }else if (substring.endsWith(pft)){ + ic_img.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.fileselect_img_pfd)); + }else if (substring.endsWith(ppt)){ + ic_img.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.fileselect_img_ppt)); + }else if (substring.endsWith("txt")){ + ic_img.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.fileselect_img_txt)); + }else { + ic_img.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.fileselect_img_unknown)); + } + } + } + } + private String wd = "doc,docx"; + private String ex = "xls,xlsx"; + private String zip = "rar,zip"; + private String ppt = "ppt"; + private String pft = "pfd"; + + public static void loadVideoScreenshot(final Context context, String url, ImageView imageView) { + String imgUrl = AppCache.BASE_IMAGE_URL + url; + Glide.with(context) + .setDefaultRequestOptions( + new RequestOptions() + .frame(0) + .centerCrop() + ) + .load(imgUrl) + .into(imageView); + } + + private void setImg(ImageView img, String url){ + String imgUrl = AppCache.BASE_IMAGE_URL + url; + //图片加载自己实现 + Glide.with(img) + .load(imgUrl) + .into(img); + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/ApplicationGuideAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/ApplicationGuideAdapter.java new file mode 100644 index 0000000..62403d4 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/ApplicationGuideAdapter.java @@ -0,0 +1,130 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.m.adapterbean.AppInfoBean; +import com.ycgis.macall.personalcenter.p.request.LoadAppCenterImage; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2022/11/10 19:21 + * copyright: @ruansee.com + * Describe: + */ +public class ApplicationGuideAdapter extends BaseRecyclerAdapter { + private LoadAppCenterImage loadAppCenterImage; + + public ApplicationGuideAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 0||viewType == -1){ + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_error,parent,false); + return new ErrorViewHolder(view); + } + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_app_operation,parent,false); +// ItemAppInfoBinding inflate = ItemAppInfoBinding.inflate(LayoutInflater.from(parent.getContext())); + return new AppHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + if (viewHolder instanceof AppHolder) { + AppHolder holder = (AppHolder) viewHolder; + AppInfoBean dataItem = getDataItem(position); +// if (1 == dataItem.getAttribution()) { +// if (loadAppCenterImage == null) { +// loadAppCenterImage = new LoadAppCenterImage(); +// } +// Bitmap bitmap = loadAppCenterImage.loadBitmapText(context, holder.ivAppIcon, dataItem.getIcon(), new ImageCallBack() { +// @Override +// public void imageLoad(ImageView imageView, Bitmap bitmap) { +// imageView.setImageBitmap(bitmap); +// } +// +// @Override +// public void imageLoadError(ImageView imageView, String message) { +// if (context == null||((Activity) context).isDestroyed()) return; +// Glide.with(context) +// .load(R.drawable.ic_load_imag_eerror) +// .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) +// .into(imageView); +// } +// }); +// if (bitmap!= null){ +// holder.ivAppIcon.setImageBitmap(bitmap); +// } +// } else { + setImg(holder.ivAppIcon, dataItem.getIconUrl()); +// } +// holder.ivAppIcon.setImageDrawable(ContextCompat.getDrawable(context,dataItem.getIcon())); + holder.tvAppName.setText(dataItem.getName()); + holder.tvAppCompany.setText(dataItem.getServiceProvider()); + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder){ + ErrorViewHolder holder = (ErrorViewHolder)viewHolder; + if (getDataItem(position).getBaseType() == 0){ + holder.setEmpty(getDataItem(position).getBaseMessage()); + }else { + holder.setError(getDataItem(position).getBaseMessage()); + } + } + } + + private void setImg(ImageView img,String url){ + //图片加载自己实现 + Glide.with(img) + .load(url) + .placeholder(R.drawable.icon_error2) + .error(R.drawable.ic_load_imag_eerror) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) + .into(img); + } + + private class AppHolder extends ViewHolder { + private ImageView ivAppIcon; + private TextView tvAppCompany; + private TextView tvAppName; + + public AppHolder(View itemView) { + super(itemView); + ivAppIcon = itemView.findViewById(R.id.iv_app_icon); + tvAppCompany = itemView.findViewById(R.id.tv_app_company); + tvAppName = itemView.findViewById(R.id.tv_app_name); + if (listClickListener!=null){ + itemView.findViewById(R.id.linearLayout3).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + listClickListener.onItemClickListener(v,getAdapterPosition()); + } + }); + } + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/ApplyAuditRecordAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/ApplyAuditRecordAdapter.java new file mode 100644 index 0000000..5863f20 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/ApplyAuditRecordAdapter.java @@ -0,0 +1,100 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.graphics.Bitmap; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ItemApplyAuditRecordBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.ApplyAuditBean; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.p.callback.ImageCallBack; +import com.ycgis.macall.personalcenter.p.request.AsyncBitmapLoader; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/4 15:29 + * copyright: @ruansee.com + * Describe: + */ +public class ApplyAuditRecordAdapter extends BaseRecyclerAdapter { + + public ApplyAuditRecordAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 1){ + View view = bindView(parent, R.layout.item_apply_audit_record); + ItemApplyAuditRecordBinding bind = ItemApplyAuditRecordBinding.bind(view); + return new ViewDataBindingHolder<>(bind); + } + if (viewType == 0||viewType == -1){ + View view = bindView(parent, R.layout.item_error_empty_xiao); + return new ErrorViewHolder(view); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + BaseBean dataItem = getDataItem(position); + if (viewHolder instanceof BaseRecyclerAdapter.ViewDataBindingHolder){ + ViewDataBindingHolder holder = (ViewDataBindingHolder) viewHolder; + ApplyAuditBean bean = (ApplyAuditBean) dataItem; + holder.viewBind.setData(bean); + holder.viewBind.tvResult.setTextColor(ContextCompat.getColor(context,bean.stateColor())); + holder.viewBind.tvResult.setBackground(ContextCompat.getDrawable(context,bean.stateBG())); + if ("1".equals(bean.getSealStatus())){ + loadSeal(bean,holder.viewBind.ivYz); + } + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder){{ + ErrorViewHolder holder =(ErrorViewHolder) viewHolder; + if (dataItem.getBaseType()== 0){ + holder.setEmpty(dataItem.getBaseMessage()); + }else { + holder.setError(dataItem.getBaseMessage()); + } + }} + } + + private void loadSeal(ApplyAuditBean bean, ImageView iv){ + AsyncBitmapLoader asyncBitmapLoader = new AsyncBitmapLoader(); + iv.setTag(bean.getSealDeptId()); + Bitmap bitmap = asyncBitmapLoader.loadSeal( bean.getId(), bean.getSealDeptId(), iv,new ImageCallBack() { + @Override + public void imageLoad(ImageView imageView, Bitmap bitmap) { + if (bean.getSealDeptId().equals(imageView.getTag())){ + imageView.setImageBitmap(bitmap); + } + } + + @Override + public void imageLoadError(ImageView imageView, String message) { + + } + }); + if (bitmap!=null){ + iv.setImageBitmap(bitmap); + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/ApplyForMainAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/ApplyForMainAdapter.java new file mode 100644 index 0000000..0231eee --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/ApplyForMainAdapter.java @@ -0,0 +1,76 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ItemApplyForMainButtonBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.ActionBean; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/5/31 10:52 + * copyright: @ruansee.com + * Describe: + */ +public class ApplyForMainAdapter extends BaseRecyclerAdapter { + public ApplyForMainAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 1){ + View view = bindView(parent, R.layout.item_apply_for_main_button); + ItemApplyForMainButtonBinding buttonBinding = ItemApplyForMainButtonBinding.bind(view); + return new ViewBindingHolder<>(buttonBinding); + } + if (viewType == 0||viewType == -1){ + View view = bindView(parent, R.layout.item_error); + return new ErrorViewHolder(view); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + if (viewHolder instanceof ViewBindingHolder){ + ViewBindingHolder holder =(ViewBindingHolder) viewHolder; + if (holder.viewBind instanceof ItemApplyForMainButtonBinding){ + ItemApplyForMainButtonBinding binding = (ItemApplyForMainButtonBinding) holder.viewBind; + ActionBean bean = (ActionBean) getDataItem(position); + binding.ivIcon.setImageDrawable(ContextCompat.getDrawable(context,bean.getIconId())); + binding.tvName.setText(bean.getName()); + } + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder){ + ErrorViewHolder holder = (ErrorViewHolder) viewHolder; + BaseBean dataItem = getDataItem(position); + if (dataItem.getBaseType() == 0){ + holder.setEmpty(dataItem.getBaseMessage()); + }else { + holder.setError(dataItem.getBaseMessage()); + } + } + } + + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/AuthManageAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/AuthManageAdapter.java new file mode 100644 index 0000000..121c869 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/AuthManageAdapter.java @@ -0,0 +1,127 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.content.Intent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.rs.macall.androidx.basemodel.base.BaseRecyclerPlusAdapter; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ItemApplyAuditBinding; +import com.ycgis.macall.personalcenter.databinding.ItemAuthenticationBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.AuthManageItem; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/17 15:23 + * copyright: @ruansee.com + * Describe: + */ +public class AuthManageAdapter extends BaseRecyclerPlusAdapter { + + public AuthManageAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @Override + public BaseRecyclerPlusAdapter.ViewHolder getViewHolder(@NotNull ViewGroup parent, int viewType) { + if (viewType == 0 || viewType == -1) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_error_empty_xiao, parent, false); + return new ErrorViewHolder(view); + } + if (viewType == 1) { + View view = bindView(parent, R.layout.item_authentication); + ItemAuthenticationBinding binding = ItemAuthenticationBinding.bind(view); + return new ViewBindingHolder<>(binding); + } + return null; + } + + @Override + public void bindViewHolder(@NotNull BaseRecyclerPlusAdapter.ViewHolder viewHolder, int position, @NotNull List payloads) { + AuthManageItem item = getDataItem(position); + if (payloads.isEmpty()) { + if (viewHolder instanceof ViewBindingHolder) { + ViewBindingHolder holder = (ViewBindingHolder) viewHolder; + holder.viewBind.tvTitle.setText(item.getName()); + // 是否一开通 + if (item.isActivate()) { + // 已开通的 有三中状态 1 默认绑定不支持修改 2 未绑定 需要绑定 3 已绑定支持修改 + if (item.isAutheType()){//已绑定 + if (item.isUpdate()){//支持修改 + holder.viewBind.btnUpdate.setText("修改"); + holder.viewBind.tvStauts.setVisibility(View.GONE); + holder.viewBind.btnUpdate.setVisibility(View.VISIBLE); + holder.viewBind.btnUpdate.setBackground(ContextCompat.getDrawable(context, R.drawable.back_opinion1)); + holder.viewBind.btnUpdate.setTextColor(ContextCompat.getColor(context, R.color.colorYellow7)); + }else { + holder.viewBind.tvStauts.setText("已绑定/不支持修改"); + holder.viewBind.tvStauts.setVisibility(View.VISIBLE); + holder.viewBind.btnUpdate.setVisibility(View.GONE); + } + }else {//未绑定的 + holder.viewBind.tvStauts.setVisibility(View.GONE); + holder.viewBind.btnUpdate.setVisibility(View.VISIBLE); + holder.viewBind.btnUpdate.setText("设置"); + holder.viewBind.btnUpdate.setBackground(ContextCompat.getDrawable(context, R.drawable.edit_brack_select)); + holder.viewBind.btnUpdate.setTextColor(ContextCompat.getColor(context, R.color.colorBluen6)); + } + }else { + holder.viewBind.tvStauts.setText("暂未开通"); + holder.viewBind.tvStauts.setVisibility(View.VISIBLE); + holder.viewBind.btnUpdate.setVisibility(View.GONE); + return; + } + if (item.isSelect()) { + holder.viewBind.imageView3.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_network_normal)); + } else { + holder.viewBind.imageView3.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_network_pause)); + } + holder.setChileViewClick(holder.viewBind.btnUpdate, position, 1, ""); + + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder) { + ErrorViewHolder holder = (ErrorViewHolder) viewHolder; + if (getDataItem(position).getBaseType() == 0) { + holder.setEmpty(getDataItem(position).getBaseMessage()); + } else { + holder.setError(getDataItem(position).getBaseMessage()); + } + } + }else { + Object o = payloads.get(0); + if (o instanceof Integer){ + int a = (int) o; + if (a == 5){ + if (viewHolder instanceof ViewBindingHolder) { + ViewBindingHolder holder = (ViewBindingHolder) viewHolder; + if (item.isSelect()) { + holder.viewBind.imageView3.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_network_normal)); + } else { + holder.viewBind.imageView3.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_network_pause)); + } + } + } + } + } + + + } + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/FeedBackListAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/FeedBackListAdapter.java new file mode 100644 index 0000000..f2a8a8d --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/FeedBackListAdapter.java @@ -0,0 +1,82 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ItmeFeedbackListBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.FeedbackBean; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/16 16:39 + * copyright: @ruansee.com + * Describe: + */ +public class FeedBackListAdapter extends BaseRecyclerAdapter { + + public FeedBackListAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 0 || viewType == -1) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_error_empty_xiao, parent, false); + return new ErrorViewHolder(view); + } + if (viewType == 1){ + View view = bindView(parent,R.layout.itme_feedback_list); + ItmeFeedbackListBinding binding = ItmeFeedbackListBinding.bind(view); + return new ViewDataBindingHolder<>(binding); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + if (viewHolder instanceof ViewDataBindingHolder){ + ViewDataBindingHolder holder = (ViewDataBindingHolder )viewHolder; + FeedbackBean dataItem = getDataItem(position); + holder.viewBind.setData(dataItem); + if (StringUtil.isNullOrEmpty(dataItem.getApplicationName())){ + holder.viewBind.feedbackBqAppName.setVisibility(View.GONE); + }else { + holder.viewBind.feedbackBqAppName.setText(dataItem.getApplicationName()); + } + if (dataItem.getReplyStatus() == 0){ + holder.viewBind.feedbackTvReply.setBackground(ContextCompat.getDrawable(context,R.drawable.bk_gray)); + holder.viewBind.feedbackTvReply.setTextColor(ContextCompat.getColor(context,R.color.colorGrey6)); + }else { + holder.viewBind.feedbackTvReply.setBackground(ContextCompat.getDrawable(context,R.drawable.bk_ls)); + holder.viewBind.feedbackTvReply.setTextColor(ContextCompat.getColor(context,R.color.colorGreen6)); + } + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder) { + ErrorViewHolder holder = (ErrorViewHolder) viewHolder; + if (getDataItem(position).getBaseType() == 0) { + holder.setEmpty(getDataItem(position).getBaseMessage()); + } else { + holder.setError(getDataItem(position).getBaseMessage()); + } + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/FrequentlyQuestionsAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/FrequentlyQuestionsAdapter.java new file mode 100644 index 0000000..ad7d542 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/FrequentlyQuestionsAdapter.java @@ -0,0 +1,97 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.RecyclerView; + +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ItemFrequentlyQuestionsBinding; +import com.ycgis.macall.personalcenter.databinding.ItemFrequentlyTitleBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.m.adapterbean.FrequentlyItemBean; +import com.ycgis.macall.personalcenter.m.requestbean.FrequentlyBean; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/7 14:58 + * copyright: @ruansee.com + * Describe: + */ +public class FrequentlyQuestionsAdapter extends BaseRecyclerAdapter { + + public FrequentlyQuestionsAdapter(Context context, List dataList) { + super(context, dataList); + } + + //1 大标题 2 问题标题 3 结尾标题 + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 0 || viewType == -1) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_error, parent, false); + return new ErrorViewHolder(view); + } + if (viewType == 1){ + View view = bindView(parent,R.layout.item_frequently_title); + ItemFrequentlyTitleBinding binding = ItemFrequentlyTitleBinding.bind(view); + return new ViewBindingHolder<>(binding); + } + if (viewType == 2||viewType == 3){ + View view = bindView(parent,R.layout.item_frequently_questions); + ItemFrequentlyQuestionsBinding binding = ItemFrequentlyQuestionsBinding.bind(view); + return new ViewBindingHolder<>(binding); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + if (viewHolder instanceof BaseRecyclerAdapter.ViewBindingHolder){ + ViewBindingHolder holder = (ViewBindingHolder)viewHolder; + if (holder.viewBind instanceof ItemFrequentlyTitleBinding){ + ItemFrequentlyTitleBinding binding =(ItemFrequentlyTitleBinding) holder.viewBind; + FrequentlyBean dataItem = (FrequentlyBean)getDataItem(position); + binding.frequentlyTvClassification.setText(dataItem.getTitle()); + return; + } + if (holder.viewBind instanceof ItemFrequentlyQuestionsBinding){ + ItemFrequentlyQuestionsBinding binding =(ItemFrequentlyQuestionsBinding) holder.viewBind; + BaseBean dataItem1 = getDataItem(position); + if (dataItem1 instanceof FrequentlyItemBean){ + FrequentlyItemBean dataItem = (FrequentlyItemBean)getDataItem(position); + binding.frequentlyTvTitle.setText(dataItem.getProblem()); + if (dataItem.getBaseType() == 3){ + binding.getRoot().setBackground(ContextCompat.getDrawable(context,R.drawable.round_bottom_white_8)); + }else { + binding.getRoot().setBackground(ContextCompat.getDrawable(context,R.color.colorWhite)); + } + } + return; + } + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder) { + ErrorViewHolder holder = (ErrorViewHolder) viewHolder; + if (getDataItem(position).getBaseType() == 0) { + holder.setEmpty(getDataItem(position).getBaseMessage()); + } else { + holder.setError(getDataItem(position).getBaseMessage()); + } + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/HomeAppListAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/HomeAppListAdapter.java new file mode 100644 index 0000000..c204cfd --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/HomeAppListAdapter.java @@ -0,0 +1,87 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.m.adapterbean.AppBean; +import com.ycgis.macall.personalcenter.p.app.AppCache; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/10/27 15:05 + * copyright: @ruansee.com + * Describe: + */ +public class HomeAppListAdapter extends BaseRecyclerAdapter { + + public HomeAppListAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 0 || viewType == -1) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_error_empty_xiao, parent, false); + return new ErrorViewHolder(view); + } + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_home_app, parent, false); + return new SimpleViewHolder(view).findViewById(R.id.home_app_logo).findViewById(R.id.home_app_name); + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + if (viewHolder instanceof BaseRecyclerAdapter.SimpleViewHolder) { + SimpleViewHolder holder = (SimpleViewHolder) viewHolder; + ImageView view = holder.getView(R.id.home_app_logo, ImageView.class); + TextView view1 = holder.getView(R.id.home_app_name, TextView.class); + AppBean dataItem = getDataItem(position); + view1.setText(dataItem.getAppName()); + if (StringUtil.hasContent(dataItem.getIconUrl())) { + setImg(view, dataItem.getIconUrl()); + } else if (dataItem.getIcon() != 0) { + view.setImageDrawable(ContextCompat.getDrawable(context, dataItem.getIcon())); + } + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder) { + ErrorViewHolder holder = (ErrorViewHolder) viewHolder; + if (getDataItem(position).getBaseType() == 0) { + holder.setEmpty(getDataItem(position).getBaseMessage()); + } else { + holder.setError(getDataItem(position).getBaseMessage()); + } + } + } + + private void setImg(ImageView img, String url) { + String imgUrl = AppCache.BASE_IMAGE_URL + url; + //图片加载自己实现 + Glide.with(img) + .load(imgUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) + .into(img); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/InitiateRecordAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/InitiateRecordAdapter.java new file mode 100644 index 0000000..4b76c99 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/InitiateRecordAdapter.java @@ -0,0 +1,161 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ItemApplyAuditBinding; +import com.ycgis.macall.personalcenter.databinding.ItemApplyInitiateRecordBinding; +import com.ycgis.macall.personalcenter.databinding.ItemApplyMyAuditRecordBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.ApplyBean; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.p.callback.OnAdapterLongClickListener; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/4 15:22 + * copyright: @ruansee.com + * Describe: + */ +public class InitiateRecordAdapter extends BaseRecyclerAdapter { + private OnAdapterLongClickListener longClickListener; + + public InitiateRecordAdapter(Context context, List dataList) { + super(context, dataList); + + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + public void setLongClickListener(OnAdapterLongClickListener longClickListener) { + this.longClickListener = longClickListener; + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 1) { + View view = bindView(parent, R.layout.item_apply_initiate_record); + ItemApplyInitiateRecordBinding binding = ItemApplyInitiateRecordBinding.bind(view); + return new ViewDataBindingHolder<>(binding); + } + if (viewType == 2) { + View view = bindView(parent, R.layout.item_apply_audit); + ItemApplyAuditBinding binding = ItemApplyAuditBinding.bind(view); + return new ViewDataBindingHolder<>(binding); + } + if (viewType == 3) { + View view = bindView(parent, R.layout.item_apply_my_audit_record); + ItemApplyMyAuditRecordBinding binding = ItemApplyMyAuditRecordBinding.bind(view); + return new ViewDataBindingHolder<>(binding); + } + if (viewType == 0 || viewType == -1) { + View view = bindView(parent, R.layout.item_error); + return new ErrorViewHolder(view); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position, @NonNull @NotNull List payloads) { + if (payloads.isEmpty()) { + super.onBindViewHolder(viewHolder, position, payloads); + return; + } + Object o = payloads.get(0); + if (o instanceof Integer) { + if (viewHolder instanceof ViewDataBindingHolder) { + ViewDataBindingHolder holder = (ViewDataBindingHolder) viewHolder; + if (holder.viewBind instanceof ItemApplyAuditBinding) { + ApplyBean dataItem = (ApplyBean) getDataItem(position); + ItemApplyAuditBinding binding = (ItemApplyAuditBinding) holder.viewBind; + int s = (int) o; + if (s == 5) { //修改是可被修改 + if (dataItem.isMore()) { + binding.btnAuditTitle.setVisibility(View.GONE); + binding.btnSel.setVisibility(View.VISIBLE); + binding.btnSel.setClickable(false); + binding.btnSel.setFocusable(false); + binding.btnSel.setChecked(dataItem.isSel()); +// binding.btnSel.setOnCheckedChangeListener((buttonView, isChecked) -> { +// dataItem.setSel(isChecked); +// if (btnClickListener != null) { +// btnClickListener.onClickView(null, 0, 1, null); +// } +// }); + } else { + binding.btnAuditTitle.setVisibility(View.VISIBLE); + binding.btnSel.setVisibility(View.GONE); + } + } else if (s == 3) { //修改是可被修改 + binding.btnSel.setChecked(dataItem.isSel()); + } + } + } + } + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + if (viewHolder instanceof ViewDataBindingHolder) { + ViewDataBindingHolder holder = (ViewDataBindingHolder) viewHolder; + if (holder.viewBind instanceof ItemApplyInitiateRecordBinding) { + ApplyBean dataItem = (ApplyBean) getDataItem(position); + ItemApplyInitiateRecordBinding binding = (ItemApplyInitiateRecordBinding) holder.viewBind; + binding.setData(dataItem); + binding.tvState.setTextColor(ContextCompat.getColor(context, dataItem.stateColor())); + binding.tvState.setBackground(ContextCompat.getDrawable(context, dataItem.stateBG())); + } + if (holder.viewBind instanceof ItemApplyMyAuditRecordBinding) { + ApplyBean dataItem = (ApplyBean) getDataItem(position); + ItemApplyMyAuditRecordBinding binding = (ItemApplyMyAuditRecordBinding) holder.viewBind; + binding.setData(dataItem); + binding.tvState.setTextColor(ContextCompat.getColor(context, dataItem.stateColor())); + binding.tvState.setBackground(ContextCompat.getDrawable(context, dataItem.stateBG())); + } + if (holder.viewBind instanceof ItemApplyAuditBinding) { + ApplyBean dataItem = (ApplyBean) getDataItem(position); + ItemApplyAuditBinding binding = (ItemApplyAuditBinding) holder.viewBind; + if (dataItem.isMore()) { + binding.btnAuditTitle.setVisibility(View.GONE); + binding.btnSel.setVisibility(View.VISIBLE); + } else { + binding.btnAuditTitle.setVisibility(View.VISIBLE); + binding.btnSel.setVisibility(View.GONE); + binding.btnSel.setOnCheckedChangeListener((buttonView, isChecked) -> { + dataItem.setSel(isChecked); + }); + } + binding.setData(dataItem); + if (longClickListener != null) { + binding.getRoot().setOnLongClickListener(new OnAdapterLongClickListener(dataItem, position) { + @Override + protected void onLongClick(View v, BaseBean data, int position) { + longClickListener.setParam(data, position); + longClickListener.onLongClick(v); + } + }); + } + } + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder) { + ErrorViewHolder holder = (ErrorViewHolder) viewHolder; + holder.setEmpty(getDataItem(position).getBaseMessage()); + } + } + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/MainFragmentAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/MainFragmentAdapter.java new file mode 100644 index 0000000..4af7dd0 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/MainFragmentAdapter.java @@ -0,0 +1,57 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; +import androidx.viewpager2.adapter.FragmentStateAdapter; + +import com.rs.macall.androidx.basemodel.base.BaseViewBindFragment; +import com.ycgis.macall.personalcenter.p.callback.OnFragmentOnClickListener; +import com.ycgis.macall.personalcenter.v.fragment.EmptyFragment; +import com.ycgis.macall.personalcenter.v.fragment.Home2Fragment; +import com.ycgis.macall.personalcenter.v.fragment.HomeFragment; +import com.ycgis.macall.personalcenter.v.fragment.MessageFragment; +import com.ycgis.macall.personalcenter.v.fragment.MyFragment; +import com.ycgis.macall.personalcenter.v.fragment.WorkbenchFragment; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/10/25 17:11 + * copyright: @ruansee.com + * Describe: + */ +public class MainFragmentAdapter extends FragmentStateAdapter { + + + public MainFragmentAdapter(@NonNull @NotNull FragmentActivity fragmentActivity) { + super(fragmentActivity); + } + + + @NonNull + @NotNull + @Override + public BaseViewBindFragment createFragment(int position) { + if (position == 0){ + return Home2Fragment.newInstance("", ""); + }else + if (position == 1){ + return MessageFragment.newInstance(); + }else + if (position == 2){ + return WorkbenchFragment.newInstance(); + }else + if (position == 3){ + return MyFragment.newInstance(); + } + return EmptyFragment.newInstance("",""); + } + + @Override + public int getItemCount() { + return 4; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/MessageAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/MessageAdapter.java new file mode 100644 index 0000000..766820b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/MessageAdapter.java @@ -0,0 +1,127 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.m.adapterbean.MessageBean; +import com.ycgis.macall.personalcenter.p.app.AppCache; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2022/11/11 17:20 + * copyright: @ruansee.com + * Describe: + */ +public class MessageAdapter extends BaseRecyclerAdapter { + + public MessageAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 1){ + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_home_message,parent,false); + return new MessageHolder(view); + } + if (viewType == 0|| viewType == -1){ + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_error_empty_xiao,parent,false); + return new ErrorViewHolder(view); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + MessageBean dataItem = getDataItem(position); + if (viewHolder instanceof MessageHolder){ + MessageHolder holder = (MessageHolder) viewHolder; + holder.tv_app_name.setText(dataItem.getAppName()); + holder.tv_msg_title.setText(dataItem.getTitle()); + holder.tv_msg_content.setText(dataItem.getContent()); + if (dataItem.isRead()){//已读 + holder.iv_doit.setVisibility(View.GONE); + holder.tv_read_type.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.icon_record)); +// holder.iv_icon.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.ic_read)); + }else {//未读 + holder.tv_read_type.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.icon_not_record)); +// int i = position % 2; +// if (i == 0){ +// holder.iv_icon.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.ic_unread1)); +// }else { +// holder.iv_icon.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.ic_unread2)); +// } + holder.iv_doit.setVisibility(View.VISIBLE); + } + if (StringUtil.hasContent(dataItem.getAppIcon())){ + holder.setImg(holder.iv_icon,dataItem.getAppIcon()); + } + holder.tv_time.setText(dataItem.getTime()); + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder){ + ErrorViewHolder holder = (ErrorViewHolder)viewHolder; + if (dataItem.getBaseType() == 0){ + holder.setEmpty(dataItem.getBaseMessage(),R.drawable.icon_error2); + }else { + holder.setError(dataItem.getBaseMessage(),R.drawable.icon_empty); + } + } + } + + private class MessageHolder extends ViewHolder{ + private TextView tv_app_name,tv_msg_title,tv_time,tv_msg_content; + private ImageView iv_icon,iv_doit,tv_read_type; + + public MessageHolder(View itemView) { + super(itemView); + tv_app_name = itemView.findViewById(R.id.tv_app_name); + tv_read_type = itemView.findViewById(R.id.tv_read_type); + tv_msg_content = itemView.findViewById(R.id.tv_msg_content); + tv_msg_title = itemView.findViewById(R.id.tv_msg_title); + tv_time = itemView.findViewById(R.id.tv_time); + iv_icon = itemView.findViewById(R.id.iv_icon); + iv_doit = itemView.findViewById(R.id.iv_doit); + if (listClickListener!=null){ + itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + listClickListener.onItemClickListener(v,getAdapterPosition()); + } + }); + } + } + + private void setImg(ImageView img, String url) { + String imgUrl = AppCache.BASE_IMAGE_URL + url; + //图片加载自己实现 + Glide.with(img) + .load(imgUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) + .into(img); + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/MyItemAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/MyItemAdapter.java new file mode 100644 index 0000000..0fa6f0f --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/MyItemAdapter.java @@ -0,0 +1,74 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ItemHomeAppBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.MyItem; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2022/11/10 10:32 + * copyright: @ruansee.com + * Describe: + */ +public class MyItemAdapter extends BaseRecyclerAdapter,BaseRecyclerAdapter.ViewHolder> { + + public MyItemAdapter(Context context, List> dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 1){ + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_home_app, parent, false); + ItemHomeAppBinding bind = ItemHomeAppBinding.bind(view); + return new ViewBindingHolder<>(bind); +// SimpleViewHolder(view).findViewById(R.id.home_app_logo).findViewById(R.id.home_app_name); + } + if (viewType == 5){ + return new ViewHolder(bindView(parent,R.layout.item_dev_12)); + } + return new SimpleViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_my_opertion,parent,false)) + .findViewById(R.id.tv_title).findViewById(R.id.iv_icon); + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + MyItem dataItem = getDataItem(position); + if (viewHolder instanceof ViewBindingHolder){ + ViewBindingHolder holder = ( ViewBindingHolder)viewHolder; + holder.viewBind.homeAppName.setText(dataItem.getTitle()); + holder.viewBind.homeAppLogo.setImageDrawable(ContextCompat.getDrawable(context,dataItem.getIcon())); + } + if (viewHolder instanceof BaseRecyclerAdapter.SimpleViewHolder){ + SimpleViewHolder holder = (SimpleViewHolder)viewHolder; + TextView tv_title = holder.getView(R.id.tv_title, TextView.class); + ImageView iv_icon = holder.getView(R.id.iv_icon, ImageView.class); + tv_title.setText(dataItem.getTitle()); + iv_icon.setImageDrawable(ContextCompat.getDrawable(context,dataItem.getIcon())); + } + + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/SelectAddressAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/SelectAddressAdapter.java new file mode 100644 index 0000000..fcf4a31 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/SelectAddressAdapter.java @@ -0,0 +1,61 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.core.content.ContextCompat; + +import com.rs.macall.androidx.basemodel.base.BaseBackAdapter; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.m.adapterbean.SelectAddressBean; + +import java.util.List; + +/** + * created by: Macall + * create time: 2022/11/14 18:20 + * copyright: @ruansee.com + * Describe: + */ +public class SelectAddressAdapter extends BaseBackAdapter { + + public SelectAddressAdapter(Context context, List datalist) { + super(context, datalist); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + Holder holder = null; + if (convertView == null){ + convertView = LayoutInflater.from(context).inflate(R.layout.item_grid_select_ds,parent,false); + holder = new Holder(convertView); + convertView.setTag(holder); + }else { + holder = (Holder) convertView.getTag(); + } + if (getItem(position).isSelect()){ + holder.tv_name.setBackground(ContextCompat.getDrawable(context,R.drawable.bk_main_color_round_8)); + holder.tv_name.setTextColor(ContextCompat.getColor(context,R.color.mainColor)); + }else { + holder.tv_name.setBackground(ContextCompat.getDrawable(context,R.drawable.card_white_round_8)); + holder.tv_name.setTextColor(ContextCompat.getColor(context,R.color.colorGrey7)); + } + holder.tv_name.setText(getItem(position).getName()); + return convertView; + } + + private class Holder{ + private View itemView; + private TextView tv_name; + + public Holder(View itemView) { + this.itemView = itemView; + tv_name = itemView.findViewById(R.id.tv_name); + } + } + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/SelectAppAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/SelectAppAdapter.java new file mode 100644 index 0000000..4d93f31 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/SelectAppAdapter.java @@ -0,0 +1,148 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ItemSelectAppBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.AppInfoBean; +import com.ycgis.macall.personalcenter.p.request.LoadAppCenterImage; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/14 17:56 + * copyright: @ruansee.com + * Describe: + */ +public class SelectAppAdapter extends BaseRecyclerAdapter { + private LoadAppCenterImage loadAppCenterImage; + + public SelectAppAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 0 || viewType == -1) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_error, parent, false); + return new ErrorViewHolder(view); + } + if (viewType == 1) { + View view = bindView(parent, R.layout.item_select_app); + ItemSelectAppBinding viewBind = ItemSelectAppBinding.bind(view); + return new ViewBindingHolder<>(viewBind); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + if (viewHolder instanceof BaseRecyclerAdapter.ViewBindingHolder) { + ViewBindingHolder holder = (ViewBindingHolder) viewHolder; + AppInfoBean dataItem = getDataItem(position); + holder.viewBind.tvAppName.setText(dataItem.getName()); + holder.viewBind.imageView16.setVisibility(View.GONE); +// if (1 == dataItem.getAttribution()) { +// if (loadAppCenterImage == null) { +// loadAppCenterImage = new LoadAppCenterImage(); +// } +// Bitmap bitmap = loadAppCenterImage.loadBitmapText(context, holder.viewBind.ivAppIcon, dataItem.getIcon(), new ImageCallBack() { +// @Override +// public void imageLoad(ImageView imageView, Bitmap bitmap) { +// imageView.setImageBitmap(bitmap); +// } +// +// @Override +// public void imageLoadError(ImageView imageView, String message) { +// if (context == null||((Activity) context).isDestroyed()) return; +// Glide.with(context) +// .load(R.drawable.icon_error2) +// .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) +// .into(imageView); +// } +// }); +// if (bitmap!= null){ +// holder.viewBind.ivAppIcon.setImageBitmap(bitmap); +// } +// } else { + setImg(holder.viewBind.ivAppIcon, dataItem.getIconUrl()); +// } + if (dataItem.isSelect()) { + holder.viewBind.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_select)); + holder.viewBind.tvAppName.setTextColor(ContextCompat.getColor(context, R.color.blue)); + } else { + holder.viewBind.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_not_select)); + holder.viewBind.tvAppName.setTextColor(ContextCompat.getColor(context, R.color.colorGrey8)); + } + return; + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder) { + ErrorViewHolder holder = (ErrorViewHolder) viewHolder; + if (getDataItem(position).getBaseType() == 0) { + holder.setEmpty(getDataItem(position).getBaseMessage()); + } else { + holder.setError(getDataItem(position).getBaseMessage()); + } + } + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position, @NonNull @NotNull List payloads) { + if (payloads.isEmpty()) { + onBindViewHolder(viewHolder, position); + } else { + Object o = payloads.get(0); + if (o instanceof Integer) { + int a = (int) o; + if (a == 5) { + if (viewHolder instanceof BaseRecyclerAdapter.ViewBindingHolder) { + AppInfoBean dataItem = getDataItem(position); + ViewBindingHolder holder = (ViewBindingHolder) viewHolder; + if (dataItem.isSelect()) { + holder.viewBind.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_select)); +// holder.viewBind.imageView16.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_arrow_bottom)); + holder.viewBind.tvAppName.setTextColor(ContextCompat.getColor(context, R.color.blue)); + } else { + holder.viewBind.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_not_select)); + holder.viewBind.tvAppName.setTextColor(ContextCompat.getColor(context, R.color.colorGrey8)); +// holder.viewBind.imageView16.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_arrow_right)); + } + } + } + } + } + } + + private void setImg(ImageView img, String url) { +// String imgUrl = url; +// String imgUrl = "http://" + RuanseeApplication.getAppCache().getIp() + ":8080" + url; + //图片加载自己实现 + Glide.with(img) + .load(url) + .placeholder(R.drawable.icon_error2) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) + .error(R.drawable.icon_error2) + .into(img); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/SelectDeptAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/SelectDeptAdapter.java new file mode 100644 index 0000000..f2837dc --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/SelectDeptAdapter.java @@ -0,0 +1,92 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ItemSelectDeptBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.OrgBean; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/23 16:37 + * copyright: @ruansee.com + * Describe: + */ +public class SelectDeptAdapter extends BaseRecyclerAdapter { + + public SelectDeptAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 0 || viewType == -1) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_error, parent, false); + return new ErrorViewHolder(view); + } + if (viewType == 1){ + View view = bindView(parent, R.layout.item_select_dept); + ItemSelectDeptBinding bind = ItemSelectDeptBinding.bind(view); + return new ViewBindingHolder<>(bind); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + if (viewHolder instanceof ViewBindingHolder){ + ViewBindingHolder holder =(ViewBindingHolder) viewHolder; + OrgBean dataItem = getDataItem(position); + holder.viewBind.tvOrgName.setText(dataItem.getOrgName()); + if (dataItem.isSelect()){ + holder.viewBind.ivSelect.setVisibility(View.VISIBLE); + }else { + holder.viewBind.ivSelect.setVisibility(View.INVISIBLE); + } + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder) { + ErrorViewHolder holder = (ErrorViewHolder) viewHolder; + if (getDataItem(position).getBaseType() == 0) { + holder.setEmpty(getDataItem(position).getBaseMessage()); + } else { + holder.setError(getDataItem(position).getBaseMessage()); + } + } + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position, @NonNull @NotNull List payloads) { + if (payloads.isEmpty()){ + onBindViewHolder(viewHolder, position); + }else { + Object o = payloads.get(0); + if (o instanceof Integer){ + if (viewHolder instanceof ViewBindingHolder) { + ViewBindingHolder holder = (ViewBindingHolder) viewHolder; + OrgBean dataItem = getDataItem(position); if (dataItem.isSelect()){ + holder.viewBind.ivSelect.setVisibility(View.VISIBLE); + }else { + holder.viewBind.ivSelect.setVisibility(View.INVISIBLE); + } + } + } + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/SelectSystemAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/SelectSystemAdapter.java new file mode 100644 index 0000000..65e0151 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/SelectSystemAdapter.java @@ -0,0 +1,235 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ItemSelecctRoleBinding; +import com.ycgis.macall.personalcenter.databinding.ItemSelectAppBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.ApplyAppBean; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.m.adapterbean.SelectAppBean; +import com.ycgis.macall.personalcenter.m.adapterbean.SelectRoleBean; +import com.ycgis.macall.personalcenter.p.app.AppCache; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/6/1 16:25 + * copyright: @ruansee.com + * Describe: 选择系统和角色 + */ +public class SelectSystemAdapter extends BaseRecyclerAdapter { + + public SelectSystemAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 0 || viewType == -1) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_error, parent, false); + return new ErrorViewHolder(view); + } + if (viewType == 1) { + View view = bindView(parent, R.layout.item_select_app); + ItemSelectAppBinding binding = ItemSelectAppBinding.bind(view); + return new ViewBindingHolder<>(binding); + } + if (viewType == 2) { + View view = bindView(parent, R.layout.item_selecct_role); + ItemSelecctRoleBinding binding = ItemSelecctRoleBinding.bind(view); + return new ViewBindingHolder<>(binding); + } + if (viewType == 3) { + View view = bindView(parent, R.layout.item_selecct_role); + ItemSelecctRoleBinding binding = ItemSelecctRoleBinding.bind(view); + return new ShowRoleViewHolder(binding); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + if (viewHolder instanceof BaseRecyclerAdapter.ViewBindingHolder) { + ViewBindingHolder holder = (ViewBindingHolder) viewHolder; + if (holder.viewBind instanceof ItemSelectAppBinding) { + ItemSelectAppBinding binding = (ItemSelectAppBinding) holder.viewBind; + BaseBean item = getDataItem(position); + if (item instanceof SelectAppBean) { + SelectAppBean dataItem = (SelectAppBean) item; + binding.tvAppName.setText(dataItem.getAppName()); + if (dataItem.getIcon() == null) { + setImg(binding.ivAppIcon, dataItem.getIconUrl()); + } else { + //图片加载自己实现 + Glide.with(context) + .load(dataItem.getIcon()) + .placeholder(R.drawable.icon_gd) + .error(R.drawable.icon_error2) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) + .into(binding.ivAppIcon); + } + if (dataItem.isSelect()) { + binding.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_select)); + binding.tvAppName.setTextColor(ContextCompat.getColor(context, R.color.blue)); + } else { + binding.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_not_select)); + binding.tvAppName.setTextColor(ContextCompat.getColor(context, R.color.colorGrey8)); + } + } + if (item instanceof ApplyAppBean.DataBean) { + ApplyAppBean.DataBean dataItem = (ApplyAppBean.DataBean) item; + binding.tvAppName.setText(dataItem.getName()); + if (dataItem.getIcon() != null) { + Glide.with(context) + .load(dataItem.getIconUrl()) + .placeholder(R.drawable.icon_gd) + .error(R.drawable.icon_error2) + .into(binding.ivAppIcon); + } + if (dataItem.isSelect()) { + binding.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_select)); + binding.tvAppName.setTextColor(ContextCompat.getColor(context, R.color.blue)); + binding.imageView16.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_arrow_bottom)); + } else { + binding.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_not_select)); + binding.tvAppName.setTextColor(ContextCompat.getColor(context, R.color.colorGrey8)); + binding.imageView16.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_arrow_right)); + } + } + return; + } + if (holder.viewBind instanceof ItemSelecctRoleBinding) { + ItemSelecctRoleBinding binding = (ItemSelecctRoleBinding) holder.viewBind; + SelectRoleBean dataItem = (SelectRoleBean) getDataItem(position); + binding.tvAppName.setText(dataItem.getName()); + if (dataItem.isSelect()) { + binding.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.icon_item_sel)); + } else { + binding.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.select_def)); + } + return; + } + } + if (viewHolder instanceof ShowRoleViewHolder) { + ShowRoleViewHolder holder = (ShowRoleViewHolder) viewHolder; + SelectRoleBean dataItem = (SelectRoleBean) getDataItem(position); + holder.binding.tvAppName.setText(dataItem.getName()); + holder.binding.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.icon_role_sel)); + holder.binding.tvAppName.setTextColor(ContextCompat.getColor(context, R.color.colorBluen7)); + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder) { + ErrorViewHolder holder = (ErrorViewHolder) viewHolder; + if (getDataItem(position).getBaseType() == 0) { + holder.setEmpty(getDataItem(position).getBaseMessage()); + } else { + holder.setError(getDataItem(position).getBaseMessage()); + } + } + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position, @NonNull @NotNull List payloads) { + if (!payloads.isEmpty()) { + Object o = payloads.get(0); + if (!(o instanceof Integer)) return; + int a = (int) o; + if (a == 1) { + if (viewHolder instanceof BaseRecyclerAdapter.ViewBindingHolder) { + ViewBindingHolder holder = (ViewBindingHolder) viewHolder; + if (holder.viewBind instanceof ItemSelectAppBinding) { + ItemSelectAppBinding binding = (ItemSelectAppBinding) holder.viewBind; + BaseBean item = getDataItem(position); + if (item instanceof ApplyAppBean.DataBean) { + ApplyAppBean.DataBean dataItem = (ApplyAppBean.DataBean) item; + if (dataItem.isSelect()) { + binding.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_select)); + binding.imageView16.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_arrow_bottom)); + binding.tvAppName.setTextColor(ContextCompat.getColor(context, R.color.blue)); + } else { + binding.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_not_select)); + binding.tvAppName.setTextColor(ContextCompat.getColor(context, R.color.colorGrey8)); + binding.imageView16.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_arrow_right)); + } + } + + if (item instanceof SelectAppBean) { + SelectAppBean dataItem = (SelectAppBean) item; + if (dataItem.isSelect()) { + binding.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_select)); + binding.imageView16.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_arrow_bottom)); + binding.tvAppName.setTextColor(ContextCompat.getColor(context, R.color.blue)); + } else { + binding.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_not_select)); + binding.tvAppName.setTextColor(ContextCompat.getColor(context, R.color.colorGrey8)); + binding.imageView16.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_arrow_right)); + } + } + return; + } + if (holder.viewBind instanceof ItemSelecctRoleBinding) { + ItemSelecctRoleBinding binding = (ItemSelecctRoleBinding) holder.viewBind; + SelectRoleBean dataItem = (SelectRoleBean) getDataItem(position); + binding.tvAppName.setText(dataItem.getName()); + if (dataItem.isSelect()) { + binding.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.icon_item_sel)); + } else { + binding.ivSelect.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.select_def)); + } + } + } + return; + } + if (a == 6) { + if (viewHolder instanceof ShowRoleViewHolder) { + ShowRoleViewHolder holder = (ShowRoleViewHolder) viewHolder; + SelectRoleBean dataItem = (SelectRoleBean) getDataItem(position); + holder.binding.tvAppName.setText(dataItem.getName()); + } + } + } + + super.onBindViewHolder(viewHolder, position, payloads); + } + + private void setImg(ImageView img, String url) { + String imgUrl = AppCache.BASE_IMAGE_URL + url; +// String imgUrl = "http://" + RuanseeApplication.getAppCache().getIp() + ":8080" + url; + //图片加载自己实现 + Glide.with(img) + .load(imgUrl) + .placeholder(R.drawable.icon_gd) + .error(R.drawable.icon_error2) + .into(img); + } + + public class ShowRoleViewHolder extends ViewHolder { + ItemSelecctRoleBinding binding; + + public ShowRoleViewHolder(ItemSelecctRoleBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/SimStringListAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/SimStringListAdapter.java new file mode 100644 index 0000000..87f65f4 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/SimStringListAdapter.java @@ -0,0 +1,42 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.ycgis.macall.personalcenter.R; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/10/26 14:34 + * copyright: @ruansee.com + * Describe: + */ +public class SimStringListAdapter extends BaseRecyclerAdapter { + + public SimStringListAdapter(Context context, List dataList) { + super(context, dataList); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.SimpleViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + View view = bindView(parent, R.layout.item_sim_string); + return new SimpleViewHolder(view).findViewById(R.id.tv_sim_string_msg); + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.SimpleViewHolder holder, int position) { + TextView view = (TextView) holder.getView(R.id.tv_sim_string_msg, TextView.class); + view.setText(dataList.get(position)); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/TravelAssistantAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/TravelAssistantAdapter.java new file mode 100644 index 0000000..9f6c679 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/TravelAssistantAdapter.java @@ -0,0 +1,67 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ItemTravelCityBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.TravelCityBean; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/13 10:32 + * copyright: @ruansee.com + * Describe: + */ +public class TravelAssistantAdapter extends BaseRecyclerAdapter { + + public TravelAssistantAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 0 || viewType == -1) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_error_empty_xiao, parent, false); + return new ErrorViewHolder(view); + } + if (viewType == 1){ + View view = bindView(parent,R.layout.item_travel_city); + ItemTravelCityBinding binding = ItemTravelCityBinding.bind(view); + return new ViewBindingHolder<>(binding); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + if (viewHolder instanceof ViewBindingHolder){ + ViewBindingHolder holder = (ViewBindingHolder)viewHolder; + holder.viewBind.travelTvCityName.setText(getDataItem(position).getName()); + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder) { + ErrorViewHolder holder = (ErrorViewHolder) viewHolder; + if (getDataItem(position).getBaseType() == 0) { + holder.setEmpty(getDataItem(position).getBaseMessage()); + } else { + holder.setError(getDataItem(position).getBaseMessage()); + } + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/TravelSearchListAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/TravelSearchListAdapter.java new file mode 100644 index 0000000..52984cf --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/TravelSearchListAdapter.java @@ -0,0 +1,69 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ItemTravelCityListBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.TravelCityBean; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/14 9:28 + * copyright: @ruansee.com + * Describe: + */ +public class TravelSearchListAdapter extends BaseRecyclerAdapter { + + + public TravelSearchListAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 1){ + View view = bindView(parent, R.layout.item_travel_city_list); + ItemTravelCityListBinding bind = ItemTravelCityListBinding.bind(view); + return new ViewBindingHolder<>(bind); + } + if (viewType == 0 || viewType == -1) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_error_empty_xiao, parent, false); + return new ErrorViewHolder(view); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + if (viewHolder instanceof ViewBindingHolder){ + ViewBindingHolder holder = (ViewBindingHolder)viewHolder; + TravelCityBean dataItem = getDataItem(position); + holder.viewBind.travelTvCityName.setText(dataItem.getName()); + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder) { + ErrorViewHolder holder = (ErrorViewHolder) viewHolder; + if (getDataItem(position).getBaseType() == 0) { + holder.setEmpty(getDataItem(position).getBaseMessage()); + } else { + holder.setError(getDataItem(position).getBaseMessage()); + } + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/WorkAppListAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/WorkAppListAdapter.java new file mode 100644 index 0000000..581eddc --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/WorkAppListAdapter.java @@ -0,0 +1,111 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.m.adapterbean.AppBean; +import com.ycgis.macall.personalcenter.m.adapterbean.WorkAppBean; +import com.ycgis.macall.personalcenter.p.app.AppCache; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/1 10:53 + * copyright: @ruansee.com + * Describe: 永恒问道 + */ +public class WorkAppListAdapter extends BaseRecyclerAdapter { + + public WorkAppListAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 0 || viewType == -1) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_error_empty_xiao, parent, false); + return new ErrorViewHolder(view); + } + if (viewType == 5){ + View view = bindView(parent, R.layout.item_work_add_app); + return new AddHolder(view); + }else { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_home_app, parent, false); + return new SimpleViewHolder(view).findViewById(R.id.home_app_logo).findViewById(R.id.home_app_name); + } + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + if (viewHolder instanceof BaseRecyclerAdapter.SimpleViewHolder) { + SimpleViewHolder holder = (SimpleViewHolder) viewHolder; + ImageView view = holder.getView(R.id.home_app_logo, ImageView.class); + TextView view1 = holder.getView(R.id.home_app_name, TextView.class); + WorkAppBean dataItem = getDataItem(position); + view1.setText(dataItem.getAppName()); + if (StringUtil.hasContent(dataItem.getIconUrl())) { + setImg(view, dataItem.getIconUrl()); + } else if (dataItem.getApplicationIcon() != null) { + view.setImageDrawable(dataItem.getApplicationIcon()); + }else { + view.setImageDrawable(ContextCompat.getDrawable(context, dataItem.getIcon())); + } + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder) { + ErrorViewHolder holder = (ErrorViewHolder) viewHolder; + if (getDataItem(position).getBaseType() == 0) { + holder.setEmpty(getDataItem(position).getBaseMessage()); + } else { + holder.setError(getDataItem(position).getBaseMessage()); + } + } + } + + private void setImg(ImageView img, String url) { + String imgUrl = AppCache.BASE_IMAGE_URL + url; + //图片加载自己实现 + Glide.with(img) + .load(imgUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) + .into(img); + } + + public class AddHolder extends BaseRecyclerAdapter.ViewHolder{ + + public AddHolder(View itemView) { + super(itemView); + if (listClickListener!=null){ + itemView.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + listClickListener.onItemClickListener(v,getAdapterPosition()); + } + }); + } + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/WorkCustomAppAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/WorkCustomAppAdapter.java new file mode 100644 index 0000000..a0632d8 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/WorkCustomAppAdapter.java @@ -0,0 +1,107 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.Glide; +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ItemWorkManageAppBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.WorkAppBean; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/2 17:47 + * copyright: @ruansee.com + * Describe: + */ +public class WorkCustomAppAdapter extends BaseRecyclerAdapter { + + + public WorkCustomAppAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 1){ + View view = bindView(parent, R.layout.item_work_manage_app); + ItemWorkManageAppBinding binding = ItemWorkManageAppBinding.bind(view); + return new ViewDataBindingHolder<>(binding); + } + if (viewType == 0|| viewType == -1){ + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_error,parent,false); + return new ErrorViewHolder(view); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + WorkAppBean dataItem = getDataItem(position); + if (viewHolder instanceof ViewDataBindingHolder){ + ViewDataBindingHolder holder = (ViewDataBindingHolder )viewHolder; + holder.viewBind.setData(dataItem); + holder.setChileViewClick(holder.viewBind.btnAddApp,position,1,""); + holder.setChileViewClick(holder.viewBind.btnDeleteApp,position,2,""); + if (StringUtil.isNullOrEmpty(dataItem.getIconUrl())){ + if (dataItem.getApplicationIcon() == null){ + Glide.with(context).load(dataItem.getIcon()).into(holder.viewBind.ivAppIcon); + }else { + Glide.with(context).load(dataItem.getApplicationIcon()).into(holder.viewBind.ivAppIcon); + } + }else { + Glide.with(context).load(dataItem.getIconUrl()).into(holder.viewBind.ivAppIcon); + } + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder){ + ErrorViewHolder holder = (ErrorViewHolder)viewHolder; + if (dataItem.getBaseType() == 0){ + holder.setEmpty(dataItem.getBaseMessage()); + }else { + holder.setError(dataItem.getBaseMessage()); + } + } + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position, @NonNull @NotNull List payloads) { + if (payloads.isEmpty()){ + onBindViewHolder(viewHolder, position); + }else { + Object o = payloads.get(0); + if (o instanceof Integer){ +// int s = (int)o; +// if (s) + WorkAppBean dataItem = getDataItem(position); + if (viewHolder instanceof ViewDataBindingHolder) { + ViewDataBindingHolder holder = (ViewDataBindingHolder) viewHolder; + if (dataItem.isAdd()){ + holder.viewBind.btnAddApp.setVisibility(View.GONE); + holder.viewBind.btnDeleteApp.setVisibility(View.VISIBLE); + }else { + holder.viewBind.btnDeleteApp.setVisibility(View.GONE); + holder.viewBind.btnAddApp.setVisibility(View.VISIBLE); + } + } + } + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/WorkbenchCenterAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/WorkbenchCenterAdapter.java new file mode 100644 index 0000000..7617155 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/adapter/WorkbenchCenterAdapter.java @@ -0,0 +1,88 @@ +package com.ycgis.macall.personalcenter.v.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.ItemHomeAppBinding; +import com.ycgis.macall.personalcenter.databinding.ItemSelectAppBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.AppInfoBean; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/24 16:00 + * copyright: @ruansee.com + * Describe: + */ +public class WorkbenchCenterAdapter extends BaseRecyclerAdapter{ + + public WorkbenchCenterAdapter(Context context, List dataList) { + super(context, dataList); + } + + @Override + public int getItemViewType(int position) { + return getDataItem(position).getBaseType(); + } + + @NonNull + @NotNull + @Override + public BaseRecyclerAdapter.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (viewType == 0 || viewType == -1) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_error_empty_xiao, parent, false); + return new ErrorViewHolder(view); + } + if (viewType == 1){ + View view = bindView(parent, R.layout.item_home_app); + ItemHomeAppBinding bind = ItemHomeAppBinding.bind(view); + return new ViewBindingHolder<>(bind); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull BaseRecyclerAdapter.ViewHolder viewHolder, int position) { + + if (viewHolder instanceof BaseRecyclerAdapter.ViewBindingHolder) { + ViewBindingHolder holder = (ViewBindingHolder) viewHolder; + AppInfoBean dataItem = getDataItem(position); + holder.viewBind.homeAppName.setText(dataItem.getName()); + setImg(holder.viewBind.homeAppLogo, dataItem.getIconUrl()); + return; + } + if (viewHolder instanceof BaseRecyclerAdapter.ErrorViewHolder) { + ErrorViewHolder holder = (ErrorViewHolder) viewHolder; + if (getDataItem(position).getBaseType() == 0) { + holder.setEmpty(getDataItem(position).getBaseMessage()); + } else { + holder.setError(getDataItem(position).getBaseMessage()); + } + } + } + private void setImg(ImageView img, String url) { +// String imgUrl = url; +// String imgUrl = "http://" + RuanseeApplication.getAppCache().getIp() + ":8080" + url; + //图片加载自己实现 + Glide.with(img) + .load(url) + .placeholder(R.drawable.icon_error2) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) + .error(R.drawable.icon_error2) + .into(img); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/custom/HorizonSlideRecycleView.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/custom/HorizonSlideRecycleView.java new file mode 100644 index 0000000..58ed31e --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/custom/HorizonSlideRecycleView.java @@ -0,0 +1,154 @@ +package com.ycgis.macall.personalcenter.v.custom; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import static android.widget.AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL; +import static android.widget.NumberPicker.OnScrollListener.SCROLL_STATE_FLING; + +public class HorizonSlideRecycleView extends RecyclerView { + private boolean mSnapEnabled = false; + private boolean mUserScrolling = false; + private boolean mScrolling = false; + private int mScrollState; + private long lastScrollTime = 0; + private final static int MINIMUM_SCROLL_EVENT_OFFSET_MS = 20; + + public HorizonSlideRecycleView(@NonNull Context context) { + super(context); + setSnapEnabled(true); + } + + public HorizonSlideRecycleView(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + setSnapEnabled(true); + } + + public HorizonSlideRecycleView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + setSnapEnabled(true); + } + + public void setSnapEnabled(boolean enabled) { + mSnapEnabled = enabled; + if (enabled) { + addOnScrollListener(new OnScrollListener() { + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + } + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + super.onScrollStateChanged(recyclerView, newState); + if (newState == SCROLL_STATE_TOUCH_SCROLL && !mScrolling) { //正在滚动 + mUserScrolling = true; + } else if (newState == SCROLL_STATE_FLING) { + mScrolling = true; + }else if (newState == SCROLL_STATE_IDLE) {//停止滚动时 + if (mUserScrolling) { + scrollToView(getCenterView()); + } + mUserScrolling = false; + mScrolling = false; + } + mScrollState = newState; + } + }); + } else { + addOnScrollListener(null); + } + } + + @Override + public boolean dispatchTouchEvent(MotionEvent event) { + if (!mSnapEnabled) { + return super.dispatchTouchEvent(event); + } + long currentTime = System.currentTimeMillis(); + + /** if touch events are being spammed, this is due to user scrolling right after a tap, + * so set userScrolling to true **/ + if (mScrolling && mScrollState == SCROLL_STATE_TOUCH_SCROLL) { + if ((currentTime - lastScrollTime) < MINIMUM_SCROLL_EVENT_OFFSET_MS) { + mUserScrolling = true; + } + } + lastScrollTime = currentTime; + View targetView = getChildClosestToPosition((int) event.getX()); + if (!mUserScrolling) { + if (event.getAction() == MotionEvent.ACTION_UP) { + if (targetView != getCenterView()) { + scrollToView(targetView); + return true; + } + } + } + return super.dispatchTouchEvent(event); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent e) { + if (!mSnapEnabled) { + return super.onInterceptTouchEvent(e); + } + View targetView = getChildClosestToPosition((int) e.getX()); + if (targetView != getCenterView()) { + return true; + } + return super.onInterceptTouchEvent(e); + } + + private View getChildClosestToPosition(int x) { + if (getChildCount() <= 0) { + return null; + } else { + int itemWidth = getChildAt(0).getMeasuredWidth(); + int closestX = 9999; + View closestChild = null; + for (int i = 0; i < getChildCount(); i++) { + View child = getChildAt(i); + int childCenterX = ((int) child.getX() + (itemWidth / 2)); + int xDistance = childCenterX - x; + /** if child center is closer than previous closest, set it as closest **/ + if (Math.abs(xDistance) < Math.abs(closestX)) { + closestX = xDistance; + closestChild = child; + } + } + return closestChild; + } + } + + private View getCenterView() { + return getChildClosestToPosition(getMeasuredWidth() / 2); + } + + private void scrollToView(View child) { + if (child == null) + return; + stopScroll(); + int scrollDistance = getScrollDistance(child); + if (scrollDistance != 0) + smoothScrollBy(scrollDistance, 0); + } + + private int getScrollDistance(View child) { + int x = (int) child.getX(); + int scrollX = child.getScrollX(); + return x-scrollX; + } + + @Override + public boolean fling(int velocityX, int velocityY) { + // velocityY *= 0.7; + velocityX *= 0.3; //for Horizontal recycler view. comment velocityY line not require for Horizontal Mode. + + return super.fling(velocityX, velocityY); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/custom/InputDialog.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/custom/InputDialog.java new file mode 100644 index 0000000..583e600 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/custom/InputDialog.java @@ -0,0 +1,82 @@ +package com.ycgis.macall.personalcenter.v.custom; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.text.InputType; +import android.util.DisplayMetrics; +import android.view.Gravity; +import android.view.WindowManager; + +import androidx.annotation.NonNull; + +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.DialogInputBinding; + +/** + * created by: Macall + * create time: 2023/11/22 9:27 + * copyright: @ruansee.com + * Describe: + */ +public class InputDialog extends Dialog { + private DialogInputBinding binding; + + public InputDialog(@NonNull Context context) { + super(context); + } + + public InputDialog(@NonNull Context context,@NonNull int themeResId){ + super(context,themeResId); + } + + public void setSubmitListener(CustomClickListener submitListener) { + binding.btnSubmit.setOnClickListener(submitListener); + } + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = DialogInputBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + } + + public String getInputEditText(){ + return binding.editInput.getText().toString(); + } + + public void setInputEdit(String content){ + binding.editInput.setText(content); + } + + public void setInputType(int inputType){ + binding.editInput.setInputType(inputType); + } + + public void setInputEdit(CharSequence content){ + binding.editInput.setText(content); + } + + public void setInputTitle(String title){ + binding.tvTitle.setText(title); + } + + public void setInputTitle(int resTitleId){ + binding.tvTitle.setText(resTitleId); + } + + @Override + public void show() { + super.show(); + WindowManager.LayoutParams layoutParams = getWindow().getAttributes(); + layoutParams.gravity= Gravity.CENTER; +// DisplayMetrics dm = getContext().getResources().getDisplayMetrics(); +// layoutParams.width = (int)(dm.widthPixels - dm.density * horizontalMargin); + layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; + getWindow().setAttributes(layoutParams); + } + +} + diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/custom/MyTextView.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/custom/MyTextView.java new file mode 100644 index 0000000..88f145e --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/custom/MyTextView.java @@ -0,0 +1,32 @@ +package com.ycgis.macall.personalcenter.v.custom; + +import android.content.Context; +import android.graphics.Typeface; +import android.util.AttributeSet; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.jetbrains.annotations.NotNull; + +public class MyTextView extends androidx.appcompat.widget.AppCompatTextView { + + + public MyTextView(@NonNull @NotNull Context context) { + super(context); + Typeface type = Typeface.createFromAsset(context.getAssets(), "font/STXINGKA.TTF"); + setTypeface(type); + } + + public MyTextView(@NonNull @NotNull Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs) { + super(context, attrs); + Typeface type = Typeface.createFromAsset(context.getAssets(), "font/STXINGKA.TTF"); + setTypeface(type); + } + + public MyTextView(@NonNull @NotNull Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + Typeface type = Typeface.createFromAsset(context.getAssets(), "font/STXINGKA.TTF"); + setTypeface(type); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/custom/SelectAddressPopupWindow.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/custom/SelectAddressPopupWindow.java new file mode 100644 index 0000000..eb0cb4b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/custom/SelectAddressPopupWindow.java @@ -0,0 +1,79 @@ +package com.ycgis.macall.personalcenter.v.custom; + +import android.app.Activity; +import android.graphics.drawable.ColorDrawable; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.AdapterView; +import android.widget.GridView; +import android.widget.PopupWindow; + +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.m.adapterbean.SelectAddressBean; +import com.ycgis.macall.personalcenter.p.callback.SelectReturnCallback; +import com.ycgis.macall.personalcenter.v.adapter.SelectAddressAdapter; + +import java.util.ArrayList; +import java.util.List; + +/** + * created by: Macall + * create time: 2022/11/14 16:10 + * copyright: @ruansee.com + * Describe: + */ +public class SelectAddressPopupWindow extends PopupWindow { + private SelectAddressAdapter addressAdapter; + private String[] names = {"省厅:3400", "合肥:3401", "芜湖:3402", "蚌埠:3403", "淮南:3404", + "马鞍山:3405", "淮北:3406", "铜陵:3407", "安庆:3408", "黄山:3410", "滁州:3411", + "阜阳:3412", "宿州:3413", "六安:3415", "亳州:3416", "池州:3417", "宣城:3418"}; + + + public SelectAddressPopupWindow(Activity activity, SelectReturnCallback selectReturnCallback, int matchParent, int dip2px) { + View view = LayoutInflater.from(activity).inflate(R.layout.dialog_select_all_ds, null, false); + GridView view1 = view.findViewById(R.id.gv_grid); + addressAdapter = new SelectAddressAdapter(activity, getData()); + view1.setAdapter(addressAdapter); + view1.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + SelectAddressBean item = addressAdapter.getItem(position); + for (int i = 0; i getData() { + List list = new ArrayList<>(); + for (int i = 0; i < names.length; i++) { + String[] split = names[i].split(":"); + SelectAddressBean bean = new SelectAddressBean(); + bean.setName(split[0]); + bean.setCode(split[1]); + bean.setSelect(false); + list.add(bean); + } + list.get(0).setSelect(true); + return list; + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/custom/SlidingIndicatorBar.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/custom/SlidingIndicatorBar.java new file mode 100644 index 0000000..aff8e8b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/custom/SlidingIndicatorBar.java @@ -0,0 +1,174 @@ +package com.ycgis.macall.personalcenter.v.custom; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.RectF; +import android.os.Build; +import android.util.AttributeSet; +import android.view.View; + +import androidx.annotation.IntDef; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; + + +import com.ycgis.macall.personalcenter.R; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * created by: Macall + * create time: 2023/10/17 11:15 + * copyright: @ruansee.com + * Describe: + */ +public class SlidingIndicatorBar extends View { + private int barHeight; + private int barColor; + private int bendingHeight; + private float bendingRatio; + private int bendingDirection; + private Paint barPaint; + private Paint circlePaint; + private final RectF rectF = new RectF(); + private final Path path = new Path(); + + @IntDef(value = {Direction.DOWN, Direction.UP}) + @Retention(RetentionPolicy.SOURCE) + public @interface Direction { + int DOWN = 0; + int UP = 1; + } + + public SlidingIndicatorBar(Context context) { + this(context, null); + } + + public SlidingIndicatorBar(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public SlidingIndicatorBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs); + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + public SlidingIndicatorBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(context, attrs); + } + + private void init(Context context, AttributeSet attrs) { + TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SlidingIndicatorBar); + barHeight = array.getDimensionPixelSize(R.styleable.SlidingIndicatorBar_sib_bar_height, 12); + barColor = array.getColor(R.styleable.SlidingIndicatorBar_sib_bar_color, Color.LTGRAY); + bendingHeight = array.getDimensionPixelSize(R.styleable.SlidingIndicatorBar_sib_bending_height, 60); + bendingRatio = array.getFloat(R.styleable.SlidingIndicatorBar_sib_bending_ratio, 0); + bendingDirection = array.getInt(R.styleable.SlidingIndicatorBar_sib_bending_direction, Direction.DOWN); + array.recycle(); + + barPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + barPaint.setColor(barColor); + barPaint.setStyle(Paint.Style.STROKE); + barPaint.setStrokeWidth(barHeight); + barPaint.setStrokeJoin(Paint.Join.ROUND); + + circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG); + circlePaint.setColor(barColor); + circlePaint.setStyle(Paint.Style.FILL); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int width = MeasureSpec.getSize(widthMeasureSpec); + int hMode = MeasureSpec.getMode(heightMeasureSpec); + int hSize = MeasureSpec.getSize(heightMeasureSpec); + int height; + + if (hMode == MeasureSpec.EXACTLY) { + height = hSize; + } else { + if (bendingRatio <= 0) { + height = barHeight + getPaddingTop() + getPaddingBottom(); + } else { + int h = (int) (barHeight + bendingHeight * bendingRatio); + height = Math.min(h + getPaddingTop() + getPaddingBottom(), hSize); + } + } + setMeasuredDimension(width, height); + } + + @Override + protected void onDraw(Canvas canvas) { + float radius = barHeight / 2f; + if (bendingRatio <= 0) { + rectF.set(getPaddingLeft(), getPaddingTop(), + getWidth() - getPaddingRight(), getPaddingTop() + barHeight); + barPaint.setStyle(Paint.Style.FILL); + canvas.drawRoundRect(rectF, radius, radius, barPaint); + } else { + if (bendingDirection == Direction.UP) { + drawArrowUp(canvas, radius); + } else { + drawArrowDown(canvas, radius); + } + } + } + + private void drawArrowDown(Canvas canvas, float radius) { + path.reset(); + path.moveTo(getPaddingLeft() + radius, getPaddingTop() + radius); + float x = getPaddingLeft() + (getWidth() - getPaddingLeft() - getPaddingRight()) / 2f; + float y = getPaddingTop() + barHeight / 2f + bendingHeight * bendingRatio; + path.lineTo(x, y); + path.lineTo(getWidth() - getPaddingRight() - radius, getPaddingTop() + radius); + barPaint.setStyle(Paint.Style.STROKE); + canvas.drawPath(path, barPaint); + canvas.drawCircle(getPaddingLeft() + radius, getPaddingTop() + radius, + radius, circlePaint); + canvas.drawCircle(getWidth() - getPaddingRight() - radius, getPaddingTop() + radius, + radius, circlePaint); + } + + private void drawArrowUp(Canvas canvas, float radius) { + path.reset(); + path.moveTo(getPaddingLeft() + radius, getHeight() - getPaddingBottom() - radius); + float x = getPaddingLeft() + (getWidth() - getPaddingLeft() - getPaddingRight()) / 2f; + float y = getPaddingTop() + barHeight / 2f; + path.lineTo(x, y); + path.lineTo(getWidth() - getPaddingRight() - radius, getHeight() - getPaddingBottom() - radius); + barPaint.setStyle(Paint.Style.STROKE); + canvas.drawPath(path, barPaint); + canvas.drawCircle(getPaddingLeft() + radius, getHeight() - getPaddingBottom() - radius, + radius, circlePaint); + canvas.drawCircle(getWidth() - getPaddingRight() - radius, getHeight() - getPaddingBottom() - radius, + radius, circlePaint); + } + + /** + * 设置最大弯曲高度 + * + * @param height 最大弯曲高度 + */ + public void setBendingHeight(int height) { + this.bendingHeight = height; + requestLayout(); + } + + /** + * 设置弯曲比例 + * + * @param ratio 比例 + */ + public void setBendingRatio(float ratio) { + this.bendingRatio = ratio; + requestLayout(); + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/ApplyOkFragment.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/ApplyOkFragment.java new file mode 100644 index 0000000..d9b8a60 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/ApplyOkFragment.java @@ -0,0 +1,281 @@ +package com.ycgis.macall.personalcenter.v.fragment; + +import android.content.Intent; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; + +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewBindFragment; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.decoration.MyDividerItemDecoration; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.FragmentApplyOkBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.ApplyBean; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.v.activity.applyfo.ApplyDetailsActivity; +import com.ycgis.macall.personalcenter.v.activity.applyfo.ApplyForMainActivity; +import com.ycgis.macall.personalcenter.v.adapter.InitiateRecordAdapter; + +import org.jetbrains.annotations.NotNull; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link ApplyOkFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class ApplyOkFragment extends BaseViewBindFragment { + private InitiateRecordAdapter adapter; + private int page; + private final int pageSize = 10; + private int total; + private int refreshType; + + // TODO: Rename parameter arguments, choose names that match + // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER + private static final String ARG_PARAM1 = "param1"; + private static final String ARG_PARAM2 = "param2"; + + // TODO: Rename and change types of parameters + private String mParam1; + private String mParam2; + + public ApplyOkFragment() { + // Required empty public constructor + } + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @param param1 Parameter 1. + * @param param2 Parameter 2. + * @return A new instance of fragment ApplyOkFragment. + */ + // TODO: Rename and change types and number of parameters + public static ApplyOkFragment newInstance(String param1, String param2) { + ApplyOkFragment fragment = new ApplyOkFragment(); + Bundle args = new Bundle(); + args.putString(ARG_PARAM1, param1); + args.putString(ARG_PARAM2, param2); + fragment.setArguments(args); + return fragment; + } + + @Override + protected FragmentApplyOkBinding getViewBinding() { + return FragmentApplyOkBinding.inflate(getLayoutInflater()); + } + + @Override + protected void lazyLoad() { + + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void initView(View view) { + LinearLayoutManager manager = new LinearLayoutManager(getContext()); + manager.setOrientation(LinearLayoutManager.VERTICAL); + viewBinding.rvAppList.addItemDecoration(new MyDividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL)); + viewBinding.rvAppList.setLayoutManager(manager); + SmartRefreshLayoutHelp.setRefreshAndLoad(getContext(), viewBinding.srlRefresh); + } + + @Override + protected void startView(View view) { + viewBinding.srlRefresh.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull @NotNull RefreshLayout refreshLayout) { + if (page * pageSize >= total) { + viewBinding.srlRefresh.finishLoadMoreWithNoMoreData(); + return; + } + refreshType = 2; + page++; + getData(); + } + + @Override + public void onRefresh(@NonNull @NotNull RefreshLayout refreshLayout) { + viewBinding.srlRefresh.resetNoMoreData(); + page = 1; + refreshType = 1; + getData(); + } + }); + viewBinding.srlRefresh.autoRefresh(); + } + + private void getErrorList(int type, String msg) { + List baseBeans = new ArrayList<>(); + BaseBean baseBean = new BaseBean() { + }; + baseBean.setBaseType(type); + baseBean.setBaseMessage(msg); + baseBeans.add(baseBean); + initData(baseBeans); + } + + private void getData() { + Map param = new HashMap<>(); + param.put("pageNum", page); + param.put("pageSize", pageSize); + param.put("status", 1); + Map headMap = new HashMap<>(1); + headMap.put("app-yysq-token", RuanseeApplication.getAppCache().getApply_token()); + ApiModel.request(RetrofitService.getBaseInstance().applyGet(ApplyForMainActivity.BASE_URL + "apply/list", headMap, param), new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + Log.e(TAG, msg); + if (refreshType == 1) { + refreshType = 0; + viewBinding.srlRefresh.finishRefresh(); + getErrorList(0, msg); + } else { + viewBinding.srlRefresh.finishLoadMore(); + refreshType = 0; + ToastUtil.centered(getContext(), msg); + } + } + + @Override + public void onRequestSuccess(JsonObject result) { + Log.w(TAG, result.toString()); + try { + JSONObject object = new JSONObject(result.toString()); + int code = TypConversion.getJsonInt(object, "code", -1); + if (code != 200) { + getErrorList(-1, TypConversion.getJsonStr(object, "msg")); + return; + } + total = TypConversion.getJsonInt(object, "total", 0); + JSONArray rows = TypConversion.getJSONArray(object, "rows"); + if (rows == null) { + if (refreshType == 1) { + refreshType = 0; + viewBinding.srlRefresh.finishRefresh(); + getErrorList(0, "暂无已通过的申请!"); + } else { + viewBinding.srlRefresh.finishLoadMore(); + refreshType = 0; + ToastUtil.centered(getContext(), "暂无已通过的申请!"); + } + return; + } + + List dataList = new ArrayList<>(); + for (int i = 0; i < rows.length(); i++) { + JSONObject jsonObject = TypConversion.getJSONObject(rows, i); + if (jsonObject == null) continue; + int status = TypConversion.getJsonInt(jsonObject, "status", 11); + if (status== 0)continue; + ApplyBean bean = new ApplyBean(); + bean.setBaseType(1); + bean.setSysId(TypConversion.getJsonStr(jsonObject,"appId")); + bean.setId(TypConversion.getJsonStr(jsonObject,"id")); + bean.setSysName(TypConversion.getJsonStr(jsonObject, "appName")); + bean.setRoleName(TypConversion.getJsonStr(jsonObject, "appRole")); + bean.setPhone(TypConversion.getJsonStr(jsonObject, "contact")); + bean.setName(TypConversion.getJsonStr(jsonObject, "nickName")); + bean.setCode(TypConversion.getJsonStr(jsonObject, "userName")); + bean.setDeptCode(TypConversion.getJsonStr(jsonObject, "deptId")); + bean.setDeptName(TypConversion.getJsonStr(jsonObject, "deptName")); + bean.setIdCordNum(TypConversion.getJsonStr(jsonObject, "idcard")); + bean.setState(TypConversion.getJsonInt(jsonObject, "status", 11)); + bean.setNode(TypConversion.getJsonStr(jsonObject, "appRole")); + bean.setTime(TypConversion.getJsonStr(jsonObject, "opTime")); + bean.setUserId(TypConversion.getJsonStr(jsonObject, "userId")); + bean.setApplyReason(TypConversion.getJsonStr(jsonObject, "reason")); + String opType = TypConversion.getJsonStr(jsonObject, "opType"); + bean.setType("申请".equals(opType) ? 1 : 2); + dataList.add(bean); + } + if (refreshType == 1) { + refreshType = 0; + viewBinding.srlRefresh.finishRefresh(); + if (dataList.isEmpty()) { + getErrorList(0, "暂无已通过的申请!"); + return; + } + initData(dataList); + } else { + viewBinding.srlRefresh.finishLoadMore(); + refreshType = 0; + if (dataList.isEmpty()) { + ToastUtil.centered(getContext(), "暂无已通过的申请!"); + return; + } + adapter.addData(dataList); + } + if (page*pageSize>=total){ + viewBinding.srlRefresh.finishLoadMoreWithNoMoreData(); + } + } catch (JSONException e) { + e.printStackTrace(); + if (refreshType == 1) { + refreshType = 0; + viewBinding.srlRefresh.finishRefresh(); + getErrorList(-1, e.getMessage()); + } else { + viewBinding.srlRefresh.finishLoadMore(); + refreshType = 0; + ToastUtil.centered(getContext(), e.getMessage()); + } + } + } + }); + } + + private void initData(List dataList) { + viewBinding.srlRefresh.finishRefresh(); + if (adapter == null) { + adapter = new InitiateRecordAdapter(getContext(), dataList); + viewBinding.rvAppList.setAdapter(adapter); + adapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + BaseBean dataItem = adapter.getDataItem(pointer); + if (dataItem instanceof ApplyBean) { + ApplyBean bean = (ApplyBean) dataItem; + Intent intent = new Intent(getContext(), ApplyDetailsActivity.class); + intent.putExtra("data", new Gson().toJson(bean)); + intent.putExtra("operatingType", 1); + startActivity(intent); + } + } + }); + } else { + adapter.upData(dataList); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/ApplyRecordFragment.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/ApplyRecordFragment.java new file mode 100644 index 0000000..01dde58 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/ApplyRecordFragment.java @@ -0,0 +1,297 @@ +package com.ycgis.macall.personalcenter.v.fragment; + +import android.content.Intent; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; + +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewBindFragment; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.decoration.MyDividerItemDecoration; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.FragmentApplyRecordBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.ApplyBean; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.v.activity.applyfo.ApplyDetailsActivity; +import com.ycgis.macall.personalcenter.v.activity.applyfo.ApplyForMainActivity; +import com.ycgis.macall.personalcenter.v.adapter.InitiateRecordAdapter; + +import org.jetbrains.annotations.NotNull; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link ApplyRecordFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class ApplyRecordFragment extends BaseViewBindFragment { + private InitiateRecordAdapter adapter; + private int page; + private final int pageSize = 10; + private int total; + private int refreshType; + + public ApplyRecordFragment() { + // Required empty public constructor + } + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @return A new instance of fragment ApplyRecordFragment. + */ + // TODO: Rename and change types and number of parameters + public static ApplyRecordFragment newInstance() { + return new ApplyRecordFragment(); + } + + @Override + protected FragmentApplyRecordBinding getViewBinding() { + return FragmentApplyRecordBinding.inflate(getLayoutInflater()); + } + + @Override + protected void lazyLoad() { + + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void initView(View view) { + LinearLayoutManager manager = new LinearLayoutManager(getContext()); + manager.setOrientation(LinearLayoutManager.VERTICAL); + viewBinding.rvAppList.addItemDecoration(new MyDividerItemDecoration(getContext(),LinearLayoutManager.VERTICAL)); + viewBinding.rvAppList.setLayoutManager(manager); + SmartRefreshLayoutHelp.setRefreshAndLoad(getContext(), viewBinding.srlRefresh); + + } + + @Override + protected void startView(View view) { + viewBinding.srlRefresh.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull @NotNull RefreshLayout refreshLayout) { + if (page * pageSize >= total) { + viewBinding.srlRefresh.finishLoadMoreWithNoMoreData(); + return; + } + refreshType = 2; + page++; + getData(); + } + + @Override + public void onRefresh(@NonNull @NotNull RefreshLayout refreshLayout) { + viewBinding.srlRefresh.resetNoMoreData(); + page = 1; + refreshType = 1; + getData(); + } + }); + viewBinding.srlRefresh.autoRefresh(); + } + + private void getErrorList(int type, String msg) { + List baseBeans = new ArrayList<>(); + BaseBean baseBean = new BaseBean() { + }; + baseBean.setBaseType(type); + baseBean.setBaseMessage(msg); + baseBeans.add(baseBean); + initData(baseBeans); + } + + private void getData() { + Map param = new HashMap<>(); + param.put("pageNum", page); + param.put("pageSize", pageSize); + Map headMap = new HashMap<>(1); + headMap.put("app-yysq-token", RuanseeApplication.getAppCache().getApply_token()); + ApiModel.request(RetrofitService.getBaseInstance().applyGet(ApplyForMainActivity.BASE_URL + "apply/list", headMap, param), + new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + Log.e(TAG, msg); + if (refreshType == 1) { + refreshType = 0; + viewBinding.srlRefresh.finishRefresh(); + getErrorList(0, msg); + } else { + viewBinding.srlRefresh.finishLoadMore(); + refreshType = 0; + ToastUtil.centered(getContext(), msg); + } + } + + @Override + public void onRequestSuccess(JsonObject result) { + Log.w(TAG, result.toString()); + try { + JSONObject object = new JSONObject(result.toString()); + int code = TypConversion.getJsonInt(object, "code", -1); + if (code != 200) { + getErrorList(-1, TypConversion.getJsonStr(object, "msg")); + return; + } + total = TypConversion.getJsonInt(object, "total", 0); + JSONArray rows = TypConversion.getJSONArray(object, "rows"); + if (rows == null) { + if (refreshType == 1) { + refreshType = 0; + viewBinding.srlRefresh.finishRefresh(); + getErrorList(0, "暂无申请!"); + } else { + viewBinding.srlRefresh.finishLoadMore(); + refreshType = 0; + ToastUtil.centered(getContext(), "暂无申请!"); + } + return; + } + + List dataList = new ArrayList<>(); + for (int i = 0; i < rows.length(); i++) { + JSONObject jsonObject = TypConversion.getJSONObject(rows, i); + if (jsonObject == null) continue; + int status = TypConversion.getJsonInt(jsonObject, "status", 11); + if (status== 0)continue; + ApplyBean bean = new ApplyBean(); + bean.setBaseType(1); + bean.setId(TypConversion.getJsonStr(jsonObject,"id")); + bean.setSysId(TypConversion.getJsonStr(jsonObject,"appId")); + bean.setSysName(TypConversion.getJsonStr(jsonObject, "appName")); + bean.setRoleName(TypConversion.getJsonStr(jsonObject, "appRole")); + bean.setPhone(TypConversion.getJsonStr(jsonObject, "contact")); + bean.setName(TypConversion.getJsonStr(jsonObject, "nickName")); + bean.setCode(TypConversion.getJsonStr(jsonObject, "userName")); + bean.setDeptCode(TypConversion.getJsonStr(jsonObject, "deptId")); + bean.setDeptName(TypConversion.getJsonStr(jsonObject, "deptName")); + bean.setIdCordNum(TypConversion.getJsonStr(jsonObject, "idcard")); + bean.setState(TypConversion.getJsonInt(jsonObject, "status", 11)); + bean.setNode(TypConversion.getJsonStr(jsonObject, "appRole")); + bean.setTime(TypConversion.getJsonStr(jsonObject, "opTime")); + bean.setUserId(TypConversion.getJsonStr(jsonObject, "userId")); + bean.setApplyReason(TypConversion.getJsonStr(jsonObject, "reason")); + String opType = TypConversion.getJsonStr(jsonObject, "opType"); + bean.setType("申请".equals(opType) ? 1 : 2); + dataList.add(bean); + } + if (refreshType == 1) { + refreshType = 0; + viewBinding.srlRefresh.finishRefresh(); + if (dataList.isEmpty()) { + getErrorList(0, "暂无申请!"); + return; + } + initData(dataList); + } else { + viewBinding.srlRefresh.finishLoadMore(); + refreshType = 0; + if (dataList.isEmpty()) { + ToastUtil.centered(getContext(), "暂无申请!"); + return; + } + adapter.addData(dataList); + } + if (page*pageSize>=total){ + viewBinding.srlRefresh.finishLoadMoreWithNoMoreData(); + } + } catch (JSONException e) { + e.printStackTrace(); + if (refreshType == 1) { + refreshType = 0; + viewBinding.srlRefresh.finishRefresh(); + getErrorList(-1, e.getMessage()); + } else { + viewBinding.srlRefresh.finishLoadMore(); + refreshType = 0; + ToastUtil.centered(getContext(), e.getMessage()); + } + } + } + }); +// +// List dataList = new ArrayList<>(); +// ApplyBean bean = new ApplyBean(); +// bean.setBaseType(1); +// bean.setSysName("皖警云比对"); +// bean.setRoleName("高级用户"); +// bean.setName("张三"); +// bean.setCode("999099"); +// bean.setDeptCode("340000000000"); +// bean.setDeptName("安徽省公安厅"); +// bean.setIdCordNum("342422199306051513"); +// bean.setState(1); +// bean.setNode("皖警云比对运维"); +// bean.setTime("2023/05/07 15:11:23"); +// bean.setType(1); +// dataList.add(bean); +// bean = new ApplyBean(); +// bean.setBaseType(1); +// bean.setSysName("皖警云搜索"); +// bean.setRoleName("高级用户"); +// bean.setState(1); +// bean.setName("张三"); +// bean.setCode("999099"); +// bean.setDeptCode("340000000000"); +// bean.setDeptName("安徽省公安厅"); +// bean.setIdCordNum("342422199306051513"); +// bean.setNode("皖警云搜索运维"); +// bean.setTime("2023/05/01 10:10:52"); +// bean.setType(1); +// dataList.add(bean); +// initData(dataList); + } + private void initData(List dataList) { + viewBinding.srlRefresh.finishRefresh(); + if (adapter == null) { + adapter = new InitiateRecordAdapter(getContext(), dataList); + viewBinding.rvAppList.setAdapter(adapter); + adapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + BaseBean dataItem = adapter.getDataItem(pointer); + if (dataItem instanceof ApplyBean){ + ApplyBean bean = (ApplyBean) dataItem; + Intent intent = new Intent(getContext(), ApplyDetailsActivity.class); + intent.putExtra("data",new Gson().toJson(bean)); + intent.putExtra("operatingType",1); + startActivity(intent); + } + } + }); + } else { + adapter.upData(dataList); + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/EmptyFragment.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/EmptyFragment.java new file mode 100644 index 0000000..1dbee0c --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/EmptyFragment.java @@ -0,0 +1,78 @@ +package com.ycgis.macall.personalcenter.v.fragment; + +import android.os.Bundle; + +import androidx.fragment.app.Fragment; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.rs.macall.androidx.basemodel.base.BaseViewBindFragment; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.FragmentEmptyBinding; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link EmptyFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class EmptyFragment extends BaseViewBindFragment { + + // TODO: Rename parameter arguments, choose names that match + // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER + private static final String ARG_PARAM1 = "param1"; + private static final String ARG_PARAM2 = "param2"; + + // TODO: Rename and change types of parameters + private String mParam1; + private String mParam2; + + public EmptyFragment() { + // Required empty public constructor + } + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @param param1 Parameter 1. + * @param param2 Parameter 2. + * @return A new instance of fragment EmptyFragment. + */ + // TODO: Rename and change types and number of parameters + public static EmptyFragment newInstance(String param1, String param2) { + EmptyFragment fragment = new EmptyFragment(); + Bundle args = new Bundle(); + args.putString(ARG_PARAM1, param1); + args.putString(ARG_PARAM2, param2); + fragment.setArguments(args); + return fragment; + } + + @Override + protected FragmentEmptyBinding getViewBinding() { + return FragmentEmptyBinding.inflate(getLayoutInflater()); + } + + @Override + protected void lazyLoad() { + + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void initView(View view) { + + } + + @Override + protected void startView(View view) { + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/FrequentlyQuestionsDetailsFragment.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/FrequentlyQuestionsDetailsFragment.java new file mode 100644 index 0000000..ad8c0f8 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/FrequentlyQuestionsDetailsFragment.java @@ -0,0 +1,176 @@ +package com.ycgis.macall.personalcenter.v.fragment; + +import android.content.Context; +import android.graphics.Point; +import android.graphics.drawable.Drawable; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.FrameLayout; + +import com.bumptech.glide.Glide; +import com.google.android.material.bottomsheet.BottomSheetBehavior; +import com.google.android.material.bottomsheet.BottomSheetDialog; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.utils.DimensionConvert; +import com.rs.macall.androidx.basemodel.utils.MResource; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.view.Watermark; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.FragmentFrequentlyQuestionsDetailsBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.FrequentlyItemBean; +import com.ycgis.macall.personalcenter.p.app.AppCache; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.v.photoview.ShowPhotoDialog; + +import org.jetbrains.annotations.NotNull; + +import java.io.Serializable; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link FrequentlyQuestionsDetailsFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class FrequentlyQuestionsDetailsFragment extends BottomSheetDialogFragment { + private FragmentFrequentlyQuestionsDetailsBinding binding; + + // TODO: Rename parameter arguments, choose names that match + // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER + private static final String ARG_PARAM1 = "param1"; + + // TODO: Rename and change types of parameters + private String mParam1; + private String mParam2; + + public FrequentlyQuestionsDetailsFragment() { + // Required empty public constructor + } + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @param param1 Parameter 1. + * @return A new instance of fragment FrequentlyQuestionsDetailsFragment. + */ + // TODO: Rename and change types and number of parameters + public static FrequentlyQuestionsDetailsFragment newInstance(Serializable param1) { + FrequentlyQuestionsDetailsFragment fragment = new FrequentlyQuestionsDetailsFragment(); + Bundle args = new Bundle(); + args.putSerializable(ARG_PARAM1, param1); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setStyle(STYLE_NORMAL, R.style.BottomSheetDialog); + } + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + binding = FragmentFrequentlyQuestionsDetailsBinding.inflate(getLayoutInflater()); + init(); + return binding.getRoot(); + } + + private void init() { + } + + private String photoUrl; + @Override + public void onStart() { + super.onStart(); + // 设置软键盘不自动弹出 + getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); + BottomSheetDialog dialog = (BottomSheetDialog) getDialog(); + FrameLayout bottomSheet = dialog.getDelegate().findViewById(R.id.design_bottom_sheet); + if (bottomSheet != null) { + CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) bottomSheet.getLayoutParams(); + layoutParams.height = getHeight(); + BottomSheetBehavior from = BottomSheetBehavior.from(bottomSheet); +// behavior = BottomSheetBehavior.from(bottomSheet); + // 初始为展开状态 + from.setState(BottomSheetBehavior.STATE_EXPANDED); + } + + Bundle arguments = getArguments(); + if (arguments!=null){ + Serializable serializable = arguments.getSerializable(ARG_PARAM1); + FrequentlyItemBean bean = (FrequentlyItemBean)serializable; + binding.frequentlyTvExtend.setText(bean.getExtend()); + binding.frequentlyTvProblem.setText(bean.getProblem()); + String reply = bean.getReply(); + binding.frequentlyTvReply.setText(reply); + + String guidance = bean.getGuidance(); + if (StringUtil.isNullOrEmpty(guidance)){ + binding.frequentlyTvGuidance.setVisibility(View.GONE); + }else { + photoUrl =AppCache.BASE_IMAGE_URL+guidance; + binding.frequentlyTvGuidance.setVisibility(View.VISIBLE); + Glide.with(getContext()).load(photoUrl).into(binding.frequentlyTvGuidance); + binding.frequentlyTvGuidance.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + new ShowPhotoDialog(getContext(),R.style.MyDialogThemeBase).show(photoUrl); + } + }); + /* int drawable = MResource.getIdByName(getContext(), "drawable", bean.getGuidance()); + if (drawable == 0){ + binding.frequentlyTvGuidance.setVisibility(View.GONE); + }else { + try { + Drawable drawable1 = ContextCompat.getDrawable(getContext(), drawable); + binding.frequentlyTvGuidance.setVisibility(View.VISIBLE); + binding.frequentlyTvGuidance.setImageDrawable(drawable1); + binding.frequentlyTvGuidance.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + new ShowPhotoDialog(getContext()).show(binding.frequentlyTvGuidance.getDrawable()); + } + }); + }catch (Exception e){ + e.printStackTrace(); + binding.frequentlyTvGuidance.setVisibility(View.GONE); + } + }*/ + } + } + } + + + /** + * 获取屏幕高度 + * + * @return height + */ + private int getHeight() { + int height = 1920; + if (getContext() != null) { + WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); + Point point = new Point(); + if (wm != null) { + // 使用Point已经减去了状态栏高度 + wm.getDefaultDisplay().getSize(point); + height = point.y - DimensionConvert.dip2px(getContext(),120); + } + } + return height; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/Home2Fragment.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/Home2Fragment.java new file mode 100644 index 0000000..05e5e15 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/Home2Fragment.java @@ -0,0 +1,329 @@ +package com.ycgis.macall.personalcenter.v.fragment; + +import android.app.Activity; +import android.content.Intent; +import android.graphics.Bitmap; +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.lifecycle.Observer; +import androidx.lifecycle.ViewModelProviders; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; + +import android.text.Html; +import android.view.View; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.king.zxing.CameraScan; +import com.rs.macall.androidx.basemodel.base.BaseViewBindFragment; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.utils.DateUitls; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.FragmentHome2Binding; +import com.ycgis.macall.personalcenter.m.adapterbean.AppBean; +import com.ycgis.macall.personalcenter.m.adapterbean.HomeMessageBean; +import com.ycgis.macall.personalcenter.m.adapterbean.MessageBean; +import com.ycgis.macall.personalcenter.m.enumbean.AppOpenType; +import com.ycgis.macall.personalcenter.m.event.MessageEvent; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.ImageCallBack; +import com.ycgis.macall.personalcenter.p.callback.OnFragmentOnClickListener; +import com.ycgis.macall.personalcenter.p.request.LoadPhotoImage; +import com.ycgis.macall.personalcenter.util.ToThirdPartyAppUtils; +import com.ycgis.macall.personalcenter.v.activity.MainActivity; +import com.ycgis.macall.personalcenter.v.activity.MyDetailsActivity; +import com.ycgis.macall.personalcenter.v.activity.ScanCodeActivity; +import com.ycgis.macall.personalcenter.v.activity.WorkbenchCenterActivity; +import com.ycgis.macall.personalcenter.v.activity.applyfo.ApplyForMainActivity; +import com.ycgis.macall.personalcenter.v.activity.travel.TravelAssistantActivity; +import com.ycgis.macall.personalcenter.v.adapter.HomeAppListAdapter; +import com.ycgis.macall.personalcenter.v.adapter.MessageAdapter; +import com.ycgis.macall.personalcenter.v.viewmodel.HomeViewModel; +import com.youth.banner.adapter.BannerImageAdapter; +import com.youth.banner.holder.BannerImageHolder; +import com.youth.banner.indicator.RectangleIndicator; +import com.youth.banner.transformer.AlphaPageTransformer; + +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link Home2Fragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class Home2Fragment extends BaseViewBindFragment { + private HomeAppListAdapter appListAdapter; + private ToThirdPartyAppUtils appUtils; + private MessageAdapter msgAdapter; + + public static boolean isReadMsg = false; + private HomeViewModel viewModel; +// private OnFragmentOnClickListener clickListener; + + public Home2Fragment() { + // Required empty public constructor + } + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @param param1 Parameter 1. + * @param param2 Parameter 2. + * @return A new instance of fragment Home2Fragment. + */ + // TODO: Rename and change types and number of parameters + public static Home2Fragment newInstance(String param1, String param2) { + return new Home2Fragment(); + } + + @Override + protected boolean isEventBus() { + return true; + } + + @Override + protected FragmentHome2Binding getViewBinding() { + return FragmentHome2Binding.inflate(getLayoutInflater()); + } + + @Override + protected void lazyLoad() { + + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void initView(View view) { + GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 4); + viewBinding.homeAppList.setLayoutManager(gridLayoutManager); + LinearLayoutManager manager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false); + viewBinding.homeRvMsg.setLayoutManager(manager); + viewModel = ViewModelProviders.of(this).get(HomeViewModel.class); +// viewBinding.mainScanCode.setOnClickListener(v -> { +// Intent intent = new Intent(getContext(), ScanCodeActivity.class); +// startActivityForResult(intent, 15015); +// }); + } + + @Override + protected void startView(View view) { + setUserInfoUI(); + //45 *1 * 24 *20 + viewModel.addBannerData(this, this::initBanner); + viewModel.getBanner(); + viewModel.addAppList(this, this::initAppData); + viewModel.getAppList(); + viewModel.addMsgList(this, homeMessageBean -> { + viewBinding.homeTvMsgCount.setText(Html.fromHtml(homeMessageBean.getTitle())); + viewBinding.homeTvMsgCount.setTag(homeMessageBean.getCount()); + initMessage(homeMessageBean.getMessageBeanList()); + }); + viewModel.getMessage(); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void hanMessage(MessageEvent event) { + if (event.getCount() <= 0) return; + Object tag = viewBinding.homeTvMsgCount.getTag(); + if (tag != null) { + int count = (int) tag; + if (count == event.getCount()) return; + } + MessageContentFragment.isReadMsg = true; + viewBinding.homeTvMsgCount.setTag(event.getCount()); + viewBinding.homeTvMsgCount.setText(Html.fromHtml(event.getMsg())); + initMessage(event.getMessageBeanList()); + } + + + @Override + public void onResume() { + super.onResume(); + if (isReadMsg) { + viewModel.getMessage(); + isReadMsg = false; + } + } + + @Override + public void onPause() { + super.onPause(); + baseDismissDialog(); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, @Nullable @org.jetbrains.annotations.Nullable Intent data) { + if (requestCode == 15015 && resultCode == Activity.RESULT_OK) { + if (data == null) return; + String stringExtra = data.getStringExtra(CameraScan.SCAN_RESULT); + ToastUtil.centered(getContext(), stringExtra); + } + super.onActivityResult(requestCode, resultCode, data); + } + + public void getPhotoImage() { + viewBinding.homeTvUserPhoto.setImageDrawable(getDrawables(RuanseeApplication.getUserData().getErrorPhotoByIdCardNum())); + Bitmap bitmap = new LoadPhotoImage().loadPhotoImage(RuanseeApplication.getUserData().getPhoto(), viewBinding.homeTvUserPhoto, new ImageCallBack() { + @Override + public void imageLoad(ImageView imageView, Bitmap bitmap) { +// viewBinding.homeTvUserPhoto.setImageBitmap(bitmap); + if (getActivity().isDestroyed()) return; + Glide.with(getContext()) + .load(bitmap) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) + .into(viewBinding.homeTvUserPhoto); + } + + @Override + public void imageLoadError(ImageView imageView, String message) { +// ToastUtil.centered(getContext(),message); +// if (getActivity().isDestroyed())return; +// viewBinding.homeTvUserPhoto.setImageDrawable(getDrawables(RuanseeApplication.getUserData().getErrorPhotoByIdCardNum())); + } + }); + + if (bitmap != null) { + if (getActivity().isDestroyed()) return; + Glide.with(getContext()) + .load(bitmap) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) + .into(viewBinding.homeTvUserPhoto); + } + } + + /** + * 显示用户信息 + */ + private void setUserInfoUI() { + viewBinding.homeTvUserName.setText(RuanseeApplication.getUserData().getUserName()); + viewBinding.homeTvUserCode.setText(RuanseeApplication.getUserData().getUserCode()); + viewBinding.homeTvUserDeptName.setText(RuanseeApplication.getUserData().getDeptName()); + viewBinding.homeBtnUser.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + startActivity(new Intent(getContext(), MyDetailsActivity.class)); + } + }); + getPhotoImage(); + } + + private void initMessage(List dataList) { + if (msgAdapter == null) { + msgAdapter = new MessageAdapter(getContext(), dataList); + viewBinding.homeRvMsg.setAdapter(msgAdapter); + msgAdapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + if (appUtils == null) { + appUtils = new ToThirdPartyAppUtils(getContext()); + getLifecycle().addObserver(appUtils); + } + baseShowDialong("正在打开应用,请稍后。。。"); + appUtils.skipReadMsg(msgAdapter.getDataItem(pointer)); + msgAdapter.removeItem(pointer); + MessageContentFragment.isReadMsg = true; + if (msgAdapter.getItemCount() == 0) { + List messageBeanList = new ArrayList<>(); + MessageBean bean = new MessageBean(); + bean.setBaseType(0); + bean.setBaseMessage("暂无新消息!"); + messageBeanList.add(bean); + initMessage(messageBeanList); + viewBinding.homeTvMsgCount.setText("全部消息"); + viewBinding.homeTvMsgCount.setTag(0); + } else { + Object tag = viewBinding.homeTvMsgCount.getTag(); + if (tag == null) { + viewBinding.homeTvMsgCount.setText("全部消息"); + viewBinding.homeTvMsgCount.setTag(0); + } else { + int count = (int) tag; + count--; + viewBinding.homeTvMsgCount.setTag(count); + String title = "全部消息(" + count + ""; + viewBinding.homeTvMsgCount.setText(Html.fromHtml(title)); + } + } + } + }); + } else { + msgAdapter.upData(dataList); + } + } + + private void initAppData(List dataList) { + if (appListAdapter == null) { + appListAdapter = new HomeAppListAdapter(getContext(), dataList); + viewBinding.homeAppList.setAdapter(appListAdapter); + appListAdapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + if (appUtils == null) { + appUtils = new ToThirdPartyAppUtils(getContext()); + } + AppBean dataItem = appListAdapter.getDataItem(pointer); + appUtils.skipApp(dataItem); + } + }); + } else { + appListAdapter.upData(dataList); + } + if (dataList.size() == 1) { + int baseType = dataList.get(0).getBaseType(); + if (baseType == -1 || baseType == 0) { + LinearLayoutManager gridLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false); + viewBinding.homeAppList.setLayoutManager(gridLayoutManager); + return; + } + } + GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 4); + viewBinding.homeAppList.setLayoutManager(gridLayoutManager); + } + + private void initBanner(List imageViewList) { + //添加生命周期观察者 + viewBinding.homeBanner.addBannerLifecycleObserver(this) + .setLoopTime(4000) + .setIndicatorSpace(5) + .setPageTransformer(new AlphaPageTransformer()) + .setAdapter(new BannerImageAdapter(imageViewList) { + @Override + public void onBindView(Object holder, Object data, int position, int size) { + if (isDetached()) return; + if (holder instanceof BannerImageHolder) { + BannerImageHolder h = (BannerImageHolder) holder; + h.imageView.setScaleType(ImageView.ScaleType.FIT_XY); + //图片加载自己实现 + Glide.with(h.imageView) + .load(data) + .placeholder(R.drawable.icon_banner1) + .error(R.drawable.ic_load_imag_eerror) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(8))) + .into(h.imageView); + } + } + }) + .setIndicator(new RectangleIndicator(getContext())); + + viewBinding.homeBanner.start(); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/HomeFragment.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/HomeFragment.java new file mode 100644 index 0000000..1a175a0 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/HomeFragment.java @@ -0,0 +1,90 @@ +package com.ycgis.macall.personalcenter.v.fragment; + +import android.os.Bundle; + + +import android.util.Log; +import android.view.View; +import android.view.ViewOutlineProvider; + +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.google.android.material.appbar.AppBarLayout; +import com.rs.macall.androidx.basemodel.base.BaseViewBindFragment; + +import com.rs.macall.androidx.basemodel.utils.DimensionConvert; +import com.ycgis.macall.personalcenter.databinding.FragmentHomeBinding; +import com.ycgis.macall.personalcenter.v.adapter.SimStringListAdapter; + +import java.util.Arrays; + +/** + */ +public class HomeFragment extends BaseViewBindFragment { + + public HomeFragment() { + // Required empty public constructor + } + + public static HomeFragment getInstance(int position) { + Bundle bundle = new Bundle(); + bundle.putInt("position",position); + HomeFragment homeFragment = new HomeFragment(); + homeFragment.setArguments(bundle); + return homeFragment; + } + + @Override + protected FragmentHomeBinding getViewBinding() { + return FragmentHomeBinding.inflate(getLayoutInflater()); + } + + @Override + protected void lazyLoad() { + Log.w(TAG,"lazyLoad"); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + float pxz = 0.0096666666666666666666666666667f; + + @Override + protected void initView(View view) { + LinearLayoutManager manager = new LinearLayoutManager(getContext(),LinearLayoutManager.VERTICAL,false); + viewBinding.rvList.setLayoutManager(manager); + String st = "你好!欢迎大家来到欢乐大测试,请认真阅读游戏规则,并自愿遵,守游戏规则,规则如下:,1、所有人初始状态为0级,2、初始状态下无技能,3、游戏开始后所有人进入发育期,4、这是个比手速的游戏,5、每提升五级随机获取一个技能," + + "6、拥有技能后可向其他玩家发起攻击,7、技能冷却时间5分钟,8、场地只有最后一人时游戏结束,玩家胜出。,如果游戏中有人违反规则,我们将给予惩罚,lasdjfls,alsjdfl,fasdkglalsjg,asdkgas"; + SimStringListAdapter adapter = new SimStringListAdapter(getContext(), Arrays.asList(st.split(","))); + viewBinding.rvList.setAdapter(adapter); + viewBinding.appBar.setOutlineProvider(null); + viewBinding.toolbarLayout.setOutlineProvider(ViewOutlineProvider.BOUNDS); + viewBinding.appBar.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> { + int i = -DimensionConvert.px2dip(getContext(), verticalOffset); + if (i<60){ + viewBinding.mainMyTitle.getRoot().setAlpha(0); + viewBinding.mainFoldRegion.getRoot().setAlpha(1); + }else if (i<150){ + float v = i * pxz; + viewBinding.mainMyTitle.getRoot().setAlpha(v); + viewBinding.mainFoldRegion.getRoot().setAlpha(1-v); + }else { + float v = i * 0.1f; + viewBinding.mainFoldRegion.getRoot().setAlpha(0); + viewBinding.mainMyTitle.getRoot().setAlpha(v); + } + }); + } + + @Override + protected void startView(View view) { + + } + + @Override + public void onResume() { + super.onResume(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/MessageContentFragment.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/MessageContentFragment.java new file mode 100644 index 0000000..acb1d09 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/MessageContentFragment.java @@ -0,0 +1,262 @@ +package com.ycgis.macall.personalcenter.v.fragment; + +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; + +import android.view.View; + +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewBindFragment; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener; +import com.ycgis.macall.personalcenter.databinding.FragmentMessageContentBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.MessageBean; +import com.ycgis.macall.personalcenter.m.requestbean.BaseRequestModel; +import com.ycgis.macall.personalcenter.m.requestbean.PagingModel; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.util.InsertAppUtils; +import com.ycgis.macall.personalcenter.util.ToThirdPartyAppUtils; +import com.ycgis.macall.personalcenter.v.adapter.MessageAdapter; + +import org.jetbrains.annotations.NotNull; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link MessageContentFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class MessageContentFragment extends BaseViewBindFragment { + private int counts; + private int pageNum; + private final int pageSize=10; + private ToThirdPartyAppUtils appUtils; + public static boolean isReadMsg = false; + + private MessageAdapter adapter; + + // TODO: Rename parameter arguments, choose names that match + // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER + private static final String ARG_PARAM1 = "param1"; + + // TODO: Rename and change types of parameters + private boolean isRecord; + + public MessageContentFragment() { + // Required empty public constructor + } + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @return A new instance of fragment MessageContentFragment. + */ + // TODO: Rename and change types and number of parameters + public static MessageContentFragment newInstance(boolean isRecord) { + MessageContentFragment fragment = new MessageContentFragment(); + Bundle args = new Bundle(); + args.putBoolean(ARG_PARAM1, isRecord); + fragment.setArguments(args); + return fragment; + } + + @Override + protected FragmentMessageContentBinding getViewBinding() { + return FragmentMessageContentBinding.inflate(getLayoutInflater()); + } + + @Override + protected void lazyLoad() { + + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void initView(View view) { + LinearLayoutManager manager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false); + viewBinding.msgRvList.setLayoutManager(manager); + SmartRefreshLayoutHelp.setRefreshAndLoad(getContext(), viewBinding.msgSrLayout); + viewBinding.msgSrLayout.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull @NotNull RefreshLayout refreshLayout) { + if (pageNum*pageSize>=counts){ + viewBinding.msgSrLayout.finishLoadMoreWithNoMoreData(); + return; + } + pageNum++; + getMessage(); + } + + @Override + public void onRefresh(@NonNull @NotNull RefreshLayout refreshLayout) { + viewBinding.msgSrLayout.resetNoMoreData(); + pageNum = 1; + getMessage(); + } + }); + } + + @Override + protected void startView(View view) { + assert getArguments() != null; + isRecord = getArguments().getBoolean(ARG_PARAM1); + List dataList= new ArrayList<>(); + MessageBean bean = new MessageBean(); + bean.setBaseType(0); + bean.setBaseMessage("暂无消息"); + dataList.add(bean); + initMessage(dataList); + } + + @Override + public void onStart() { + super.onStart(); + } + + @Override + public void onResume() { + super.onResume(); + if (!isVisible){ + viewBinding.msgSrLayout.autoRefresh(); + isVisible = true; + } + if (!isRecord&&isRefresh){ + viewBinding.msgSrLayout.autoRefresh(); + isRefresh = false; + } + if (isReadMsg){ + viewBinding.msgSrLayout.autoRefresh(); + isReadMsg = false; + } + } + + private void hanLoadMore( List messageBeanList){ + viewBinding.msgSrLayout.finishLoadMore(); + if (messageBeanList == null||messageBeanList.isEmpty())return; + adapter.addData(messageBeanList); + } + + private boolean isRefresh = false; + private void hanRefreshMore( List messageBeanList,int type,String msg){ + viewBinding.msgSrLayout.finishRefresh(); + if (messageBeanList == null){ + messageBeanList = new ArrayList<>(); + } + if (messageBeanList.isEmpty()){ + MessageBean bean = new MessageBean(); + bean.setBaseType(type); + bean.setBaseMessage(msg); + messageBeanList.add(bean); + } + initMessage(messageBeanList); + } + + public void getMessage(){ + ApiModel.request(RetrofitService.getBaseInstance().getMessage(isRecord?1:0, pageNum, pageSize), new BaseRequestCallback>>() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(TAG, msg); + if (viewBinding.msgSrLayout.isLoading()){ + hanLoadMore(null); + } + if (viewBinding.msgSrLayout.isRefreshing()){ + hanRefreshMore(null,-1,msg); + } + } + + @Override + public void onRequestSuccess(BaseRequestModel> result) { + LogUtils.w(TAG, result.toString()); + if (result.getCode()==20041){ + PagingModel data = result.getData(); + if (data == null){ + if (viewBinding.msgSrLayout.isLoading()){ + hanLoadMore(null); + } + if (viewBinding.msgSrLayout.isRefreshing()){ + hanRefreshMore(null,-1,""); + } + return; + } + counts = data.getCounts(); + List items = data.getItems(); + if (counts<=0||items.isEmpty()){ + if (viewBinding.msgSrLayout.isLoading()){ + hanLoadMore(null); + } + if (viewBinding.msgSrLayout.isRefreshing()){ + hanRefreshMore(null,0,"暂无消息"); + } + return; + } + for (MessageBean b :items) { + b.setBaseType(1); + b.setRead(!"0".equals(b.getState())); + } + if (viewBinding.msgSrLayout.isLoading()){ + hanLoadMore(items); + } + if (viewBinding.msgSrLayout.isRefreshing()){ + hanRefreshMore(items,0,"暂无新消息"); + } + if (pageNum*pageSize>=counts){ + viewBinding.msgSrLayout.finishLoadMoreWithNoMoreData(); + } + return; + } + if (viewBinding.msgSrLayout.isLoading()){ + hanLoadMore(null); + } + if (viewBinding.msgSrLayout.isRefreshing()){ + hanRefreshMore(null,-1,result.getMsg()); + } + } + }); + } + + private void initMessage(List dataList) { + viewBinding.msgSrLayout.finishRefresh(); + if (adapter == null) { + adapter = new MessageAdapter(getContext(), dataList); + viewBinding.msgRvList.setAdapter(adapter); + adapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + if (appUtils == null){ + appUtils = new ToThirdPartyAppUtils(getContext()); + getLifecycle().addObserver(appUtils); + } + appUtils.skipReadMsg(adapter.getDataItem(pointer)); + //点击后刷新 + isRefresh = true; + if (!isRecord){ + Home2Fragment.isReadMsg = true; + } + } + }); + }else { + adapter.upData(dataList); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/MessageFragment.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/MessageFragment.java new file mode 100644 index 0000000..85f82ee --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/MessageFragment.java @@ -0,0 +1,154 @@ +package com.ycgis.macall.personalcenter.v.fragment; + +import android.content.res.ColorStateList; +import android.graphics.Color; +import android.graphics.Typeface; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.viewpager2.adapter.FragmentStateAdapter; +import androidx.viewpager2.widget.ViewPager2; + +import android.util.Log; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.WebSettings; +import android.widget.TextSwitcher; +import android.widget.TextView; + +import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; +import com.rs.macall.androidx.basemodel.base.BaseViewBindFragment; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.FragmentMessageBinding; +import com.ycgis.macall.personalcenter.v.activity.MainActivity; + +import org.jetbrains.annotations.NotNull; + +import java.time.format.TextStyle; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link MessageFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class MessageFragment extends BaseViewBindFragment { + + private FragmentAdapter adapter; + private TabLayoutMediator tabLayoutMediator; + private String[] tableName = {"未读消息", "已读消息"}; + + // TODO: Rename parameter arguments, choose names that match + + + public MessageFragment() { + // Required empty public constructor + } + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @return A new instance of fragment MessageFragment. + */ + // TODO: Rename and change types and number of parameters + public static MessageFragment newInstance() { + return new MessageFragment(); + } + + @Override + protected FragmentMessageBinding getViewBinding() { + return FragmentMessageBinding.inflate(getLayoutInflater()); + } + + @Override + protected void lazyLoad() { + + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void initView(View view) { + + } + + private int activeColor; + private int normalColor; + + @Override + protected void startView(View view) { + activeColor = getColor(R.color.blue); + normalColor = getColor(R.color.colorGrey6); + viewBinding.contentTitle.setText("待办消息"); + viewBinding.msgViewPage.setOffscreenPageLimit(2); + viewBinding.msgViewPage.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL); + viewBinding.msgViewPage.setUserInputEnabled(false); + } + + @Override + public void onResume() { + super.onResume(); + if (adapter == null) { + adapter = new FragmentAdapter(this); + viewBinding.msgViewPage.setAdapter(adapter); + tabLayoutMediator = new TabLayoutMediator(viewBinding.messageTable, viewBinding.msgViewPage, (tab, position) -> { + View view = LayoutInflater.from(getContext()).inflate(R.layout.widget_choose_icon_tag_bg, null); + TextView tv = view.findViewById(R.id.choose_icon_tab_tv); + tv.setText(tableName[position]); + int[][] states = new int[2][]; + states[0] = new int[]{android.R.attr.state_selected}; + states[1] = new int[]{}; + int[] colors = new int[]{activeColor, normalColor}; + ColorStateList colorStateList = new ColorStateList(states, colors); + tv.setTextColor(colorStateList); + tab.setCustomView(view); + }); + } + + if (tabLayoutMediator != null) { + if (!tabLayoutMediator.isAttached()) { + tabLayoutMediator.attach(); + } + } + + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (tabLayoutMediator != null) { + tabLayoutMediator.detach(); + } + } + + + public class FragmentAdapter extends FragmentStateAdapter { + + public FragmentAdapter(@NonNull @NotNull Fragment fragment) { + super(fragment); + } + + @NonNull + @NotNull + @Override + public Fragment createFragment(int position) { + if (position == 0) { + return MessageContentFragment.newInstance(false); + } + return MessageContentFragment.newInstance(true); + } + + @Override + public int getItemCount() { + return 2; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/MyFragment.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/MyFragment.java new file mode 100644 index 0000000..edb0c7b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/MyFragment.java @@ -0,0 +1,247 @@ +package com.ycgis.macall.personalcenter.v.fragment; + +import android.content.Intent; +import android.graphics.Bitmap; +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.Toolbar; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.base.BaseViewBindFragment; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.FragmentMyBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.AppBean; +import com.ycgis.macall.personalcenter.m.adapterbean.MyItem; +import com.ycgis.macall.personalcenter.p.app.AppCache; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.ImageCallBack; +import com.ycgis.macall.personalcenter.p.request.LoadPhotoImage; +import com.ycgis.macall.personalcenter.v.activity.AboutActivity; +import com.ycgis.macall.personalcenter.v.activity.ApplicationGuideActivity; +import com.ycgis.macall.personalcenter.v.activity.AuthenticationActivity; +import com.ycgis.macall.personalcenter.v.activity.FrequentlyQuestionsActivity; +import com.ycgis.macall.personalcenter.v.activity.MyDetailsActivity; +import com.ycgis.macall.personalcenter.v.activity.OpinionsSuggestionsActivity; +import com.ycgis.macall.personalcenter.v.adapter.HomeAppListAdapter; +import com.ycgis.macall.personalcenter.v.adapter.MyItemAdapter; + +import java.util.ArrayList; +import java.util.List; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link MyFragment#newInstance} factory method to + * create an instance of this fragment. + * 常见问题 Frequently Asked Questions + */ +public class MyFragment extends BaseViewBindFragment { + private MyItemAdapter adapter; +// private HomeAppListAdapter commonAdapter; + + public MyFragment() { + // Required empty public constructor + } + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @return A new instance of fragment MyFragment. + */ + // TODO: Rename and change types and number of parameters + public static MyFragment newInstance() { + return new MyFragment(); + } + + @Override + protected FragmentMyBinding getViewBinding() { + return FragmentMyBinding.inflate(getLayoutInflater()); + } + + @Override + protected void lazyLoad() { + + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void initView(View view) { + GridLayoutManager manager = new GridLayoutManager(getContext(), 3); +// LinearLayoutManager manager = new LinearLayoutManager(getContext()); + manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int position) { + int itemViewType = adapter.getItemViewType(position); + if (itemViewType == 1){ + return 1; + }else { + return 3; + } + } + }); + manager.setOrientation(LinearLayoutManager.VERTICAL); + viewBinding.myRvFunction.setLayoutManager(manager); +// viewBinding.myRvCommon.setLayoutManager(manager1); + } + + @Override + protected void startView(View view) { + + } + + @Override + public void onResume() { + super.onResume(); + getFunctionData(); + } + + public void getPhotoImage() { + viewBinding.myIvPolicePhoto.setImageDrawable(getDrawables(RuanseeApplication.getUserData().getErrorPhotoByIdCardNum())); + Bitmap bitmap = new LoadPhotoImage().loadPhotoImage(RuanseeApplication.getUserData().getPhoto(), viewBinding.myIvPolicePhoto, new ImageCallBack() { + @Override + public void imageLoad(ImageView imageView, Bitmap bitmap) { +// viewBinding.myIvPolicePhoto.setImageBitmap(bitmap); + if (getActivity().isDestroyed())return; + Glide.with(getContext()) + .load(bitmap) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) + .into(viewBinding.myIvPolicePhoto); + } + + @Override + public void imageLoadError(ImageView imageView, String message) { +// ToastUtil.centered(getContext(),message); +// viewBinding.myIvPolicePhoto.setImageDrawable(getDrawables(RuanseeApplication.getUserData().getErrorPhotoByIdCardNum())); + } + }); + + if (bitmap != null){ +// viewBinding.myIvPolicePhoto.setImageBitmap(bitmap); + Glide.with(getContext()) + .load(bitmap) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(20))) + .into(viewBinding.myIvPolicePhoto); + } + } + + + + @Override + public void onActivityResult(int requestCode, int resultCode, @Nullable @org.jetbrains.annotations.Nullable Intent data) { + if (resultCode == MyDetailsActivity.UPDATE_INFO){ + setUserInfoUI(); + } + super.onActivityResult(requestCode, resultCode, data); + } + + /** + * 显示用户信息 + */ + private void setUserInfoUI() { + viewBinding.myTvPoliceName.setText("姓名:"+RuanseeApplication.getUserData().getUserName()); + viewBinding.myTvUserCode.setText(RuanseeApplication.getUserData().getUserCode()); + viewBinding.myTvDept.setText("单位:"+RuanseeApplication.getUserData().getDeptName()); +// viewBinding.myTvPosition.setText("职务:"+RuanseeApplication.getUserData().getPolice_post()); + viewBinding.myTvPhone.setText("工作号码:"+RuanseeApplication.getUserData().getPhone1()); + getPhotoImage(); + } + + private void getFunctionData() { + setUserInfoUI(); + List> dataList = new ArrayList<>(); + MyItem bean = new MyItem(); + bean.setBaseType(1); + bean.setTitle("应用指南"); + bean.setIcon(R.drawable.icon_operation_guide); + bean.setActivityClass(ApplicationGuideActivity.class); + dataList.add(bean); + bean = new MyItem(); + bean.setBaseType(1); + bean.setTitle("意见反馈"); + bean.setIcon(R.drawable.icon_feedback); + bean.setActivityClass(OpinionsSuggestionsActivity.class); + dataList.add(bean); + bean = new MyItem(); + bean.setBaseType(1); + bean.setTitle("常见问题"); + bean.setIcon(R.drawable.icon_problen); + bean.setActivityClass(FrequentlyQuestionsActivity.class); + dataList.add(bean); + + bean = new MyItem(); + bean.setBaseType(5); + dataList.add(bean); + + MyItem item1 = new MyItem(); + item1.setIcon(R.drawable.icon_authen); + item1.setTitle("认证管理"); + item1.setActivityClass(AuthenticationActivity.class); + dataList.add(item1); + item1 = new MyItem(); + item1.setActivityClass(AboutActivity.class); + item1.setIcon(R.drawable.icon_about); + item1.setTitle("关于"); + dataList.add(item1); + initData(dataList); + } + +// private void initCommonData(List commonList) { +// if (commonAdapter == null){ +// commonAdapter = new HomeAppListAdapter(getContext(),commonList); +// viewBinding.myRvCommon.setAdapter(commonAdapter); +// commonAdapter.setListClickListener(new SimpleListClickListener() { +// @Override +// public void onSingleClick(View v, int pointer) { +// if (commonAdapter.getItemViewType(pointer)!=1)return; +// AppBean dataItem = commonAdapter.getDataItem(pointer); +// if (dataItem.getActivityClass() == null){ +// ToastUtil.centered(getContext(),"正在紧急开发中!"); +// return; +// } +// startActivity(new Intent(getContext(),dataItem.getActivityClass())); +// } +// }); +// }else { +// commonAdapter.upData(commonList); +// } +// } + + private void initData(List> dataList) { + if (adapter == null) { + adapter = new MyItemAdapter(getContext(), dataList); + adapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + MyItem dataItem = adapter.getDataItem(pointer); + if (dataItem.getActivityClass() == null) { + ToastUtil.centered(getContext(), "正在紧急开发中!"); + return; + } + startActivity(new Intent(getContext(),dataItem.getActivityClass())); + } + }); + viewBinding.myRvFunction.setAdapter(adapter); + } else { + adapter.upData(dataList); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/WorkbenchFragment.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/WorkbenchFragment.java new file mode 100644 index 0000000..835b7b9 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/WorkbenchFragment.java @@ -0,0 +1,353 @@ +package com.ycgis.macall.personalcenter.v.fragment; + +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; + +import android.util.Log; +import android.view.View; + +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewBindFragment; +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.FragmentWorkbenchBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.AppBean; +import com.ycgis.macall.personalcenter.m.adapterbean.WorkAppBean; +import com.ycgis.macall.personalcenter.m.enumbean.AppOpenType; +import com.ycgis.macall.personalcenter.m.provider.NativeAppProvider; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.callback.WorkManageCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.util.ToThirdPartyAppUtils; +import com.ycgis.macall.personalcenter.v.adapter.HomeAppListAdapter; +import com.ycgis.macall.personalcenter.v.adapter.WorkAppListAdapter; + +import org.jetbrains.annotations.NotNull; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link WorkbenchFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class WorkbenchFragment extends BaseViewBindFragment { + private HomeAppListAdapter appListAdapter; + private WorkAppListAdapter customAdapter; + private ToThirdPartyAppUtils appUtils; + private WorkbenchManageFragment workbenchManageFragment; + private NativeAppProvider provider; + + public WorkbenchFragment() { + // Required empty public constructor + } + + /** + * 5*3 =15 *25 + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @return A new instance of fragment WorkbenchFragment. + */ + // TODO: Rename and change types and number of parameters + public static WorkbenchFragment newInstance() { + return new WorkbenchFragment(); + } + + @Override + protected FragmentWorkbenchBinding getViewBinding() { + return FragmentWorkbenchBinding.inflate(getLayoutInflater()); + } + + @Override + protected void lazyLoad() { + + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void initView(View view) { + viewBinding.workCustomList.setLayoutManager(new GridLayoutManager(getContext(), 4)); + viewBinding.workRecommendedList.setLayoutManager(new GridLayoutManager(getContext(), 4)); + SmartRefreshLayoutHelp.setPullDownToRefresh(getContext(), viewBinding.workRefresh); + } + + @Override + protected void startView(View view) { + viewBinding.contentTitle.setText("工作台"); + viewBinding.workRefresh.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull @NotNull RefreshLayout refreshLayout) { + + } + + @Override + public void onRefresh(@NonNull @NotNull RefreshLayout refreshLayout) { + getRecommendedData(); + getCustomData(); + } + }); + } + + @Override + public void onResume() { + super.onResume(); + if (!isVisible) { + viewBinding.workRefresh.autoRefresh(); + isVisible = true; + } + } + + @Override + public void onStart() { + super.onStart(); + Log.w(TAG, "onStart"); + } + + @Override + public void onPause() { + super.onPause(); + baseDismissDialog(); + } + + + private void hintTuiJianApp(int type, String msg) { + List modelList1 = new ArrayList<>(); + AppBean bean = new AppBean(); + bean.setBaseType(type); + bean.setBaseMessage(msg); + modelList1.add(bean); + initRecommendedAppData(modelList1); + } + + private void getRecommendedData() { + ApiModel.request(RetrofitService.getBaseInstance().recommendApplication(), new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + Log.e(TAG, msg); + viewBinding.workRecommendedList.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); + hintTuiJianApp(-1, msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + Log.w(TAG, result.toString()); + try { + JSONObject object = new JSONObject(result.toString()); + String code = TypConversion.getJsonStr(object, "code"); + if (code.equals("20041")) { + List modelList1 = new ArrayList<>(); + JSONObject data = TypConversion.getJSONObject(object, "data"); + if (data == null) { + hintTuiJianApp(0, "暂无应用"); + return; + } + JSONArray tjyy = TypConversion.getJSONArray(data, "推荐应用"); + JSONArray zxyy = TypConversion.getJSONArray(data, "最新应用"); + if (zxyy != null) { + modelList1.addAll(hanAppData(zxyy)); + } + if (tjyy != null) { + modelList1.addAll(hanAppData(tjyy)); + } + if (modelList1.isEmpty()) { + viewBinding.workRecommendedList.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); + hintTuiJianApp(0, "暂无应用"); + } else { + AppBean bean = null; + if (modelList1.size() >= 12) { + bean = modelList1.get(11); + bean.setBaseType(1); + bean.setAppName("更多应用"); + bean.setIcon(R.drawable.icon_gd2); + bean.setIconUrl(""); + } + viewBinding.workRecommendedList.setLayoutManager(new GridLayoutManager(getContext(), 4)); + initRecommendedAppData(modelList1); + } + } else { + hintTuiJianApp(-1, TypConversion.getJsonStr(object, "msg")); + } + } catch (JSONException e) { + e.printStackTrace(); + viewBinding.workRecommendedList.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); + hintTuiJianApp(-1, e.getMessage()); + } + } + }); + } + + private List hanAppData(JSONArray array) { + List dataList = new ArrayList<>(); + for (int i = 0; i < array.length(); i++) { + JSONObject jsonObject = TypConversion.getJSONObject(array, i); + if (jsonObject == null) continue; + AppBean bean = new AppBean(); + bean.setBaseType(1); + bean.setAppName(TypConversion.getJsonStr(jsonObject, "name")); + bean.setId(TypConversion.getJsonStr(jsonObject, "id")); + bean.setAppType(TypConversion.getJsonStr(jsonObject, "level")); + if ("3".equals(bean.getAppType())) { + bean.setLinkUrl(TypConversion.getJsonStr(jsonObject, "packageName")); + } else { + bean.setLinkUrl(TypConversion.getJsonStr(jsonObject, "link")); + } + String type = TypConversion.getJsonStr(jsonObject, "type"); + if (type.equals("1")) { + bean.setNetworkType("Ⅱ类应用"); + } else if (type.equals("2")) { + bean.setNetworkType("Ⅲ类应用"); + } + bean.setClientId(TypConversion.getJsonStr(jsonObject, "clientId")); + bean.setClientSecret(TypConversion.getJsonStr(jsonObject, "clientSecret")); + bean.setIconUrl(TypConversion.getJsonStr(jsonObject, "icon")); + bean.setClassification(TypConversion.getJsonStr(jsonObject, "classification")); + bean.setCompany(TypConversion.getJsonStr(jsonObject, "serviceProvider")); + bean.setOperationName(TypConversion.getJsonStr(jsonObject, "operationPerson")); + bean.setOperationPhone(TypConversion.getJsonStr(jsonObject, "phoneNumber")); + bean.setTime(TypConversion.getJsonStr(jsonObject, "applicationTime")); + dataList.add(bean); + } + return dataList; + } + + /** + * 获取本地应用 + */ + private void getCustomData() { + if (customAdapter == null) { + if (provider == null) { + provider = new NativeAppProvider(getContext(), null); + provider.getSelCustomAppList(new BaseRequestCallback>() { + @Override + public void onRequestFailure(String msg) { + } + + @Override + public void onRequestSuccess(List result) { + WorkAppBean bean1 = new WorkAppBean(); + bean1.setBaseType(5); + result.add(bean1); + initCustomData(result); + viewBinding.workRefresh.finishRefresh(); + } + }); + } + } else { + viewBinding.workRefresh.finishRefresh(); + } + } + + private WorkManageCallback callback = new WorkManageCallback() { + @Override + public void onAdd(WorkAppBean appBean) { + customAdapter.addItem(customAdapter.getItemCount() - 1, appBean); + NativeAppProvider.cacheCustomAppList(true, appBean.getPackageName()); + } + + @Override + public void onRemove(WorkAppBean appBean) { + NativeAppProvider.cacheCustomAppList(false, appBean.getPackageName()); + List data = customAdapter.getData(); + int position = -1; + for (int i = 0; i < data.size(); i++) { + WorkAppBean bean = data.get(i); + if (appBean.getPackageName().equals(bean.getPackageName())) { + position = i; + break; + } + } + if (position > -1) { + data.remove(position); + customAdapter.notifyItemRemoved(position); + } + } + }; + + /** + * 自定因应用 + * @param dataList + */ + private void initCustomData(List dataList) { + if (customAdapter == null) { + customAdapter = new WorkAppListAdapter(getContext(), dataList); + viewBinding.workCustomList.setAdapter(customAdapter); + customAdapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + int itemViewType = customAdapter.getItemViewType(pointer); + if (itemViewType == 5) { + workbenchManageFragment = new WorkbenchManageFragment(); + workbenchManageFragment.setClickListener(callback); + List data = customAdapter.getData(); + List packageNames = new ArrayList<>(); + for (int i = 0; i < data.size(); i++) { + WorkAppBean bean = data.get(i); + if (bean.getBaseType() != 1) { + continue; + } + packageNames.add(bean.getPackageName()); + } + workbenchManageFragment.setSelectPackageNames(packageNames); + workbenchManageFragment.show(getFragmentManager(), "WorkbenchManageFragment"); + return; + } + if (appUtils == null) { + appUtils = new ToThirdPartyAppUtils(getContext()); + } + WorkAppBean dataItem = customAdapter.getDataItem(pointer); + AppBean bean = new AppBean(); + bean.setAppType("3"); + bean.setLinkUrl(dataItem.getPackageName()); + appUtils.skipLevel(bean, AppOpenType.LOGIN); + } + }); + } else { + customAdapter.upData(dataList); + } + } + + + /** + * 推荐应用 + * @param dataList + */ + private void initRecommendedAppData(List dataList) { + if (appListAdapter == null) { + appListAdapter = new HomeAppListAdapter(getContext(), dataList); + viewBinding.workRecommendedList.setAdapter(appListAdapter); + appListAdapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + if (appUtils == null) { + appUtils = new ToThirdPartyAppUtils(getContext()); + getLifecycle().addObserver(appUtils); + } + baseShowDialong("正在打开应用,请稍后..."); + appUtils.skipApp(appListAdapter.getDataItem(pointer)); + + } + }); + } else { + appListAdapter.upData(dataList); + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/WorkbenchManageFragment.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/WorkbenchManageFragment.java new file mode 100644 index 0000000..db7ac07 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/fragment/WorkbenchManageFragment.java @@ -0,0 +1,248 @@ +package com.ycgis.macall.personalcenter.v.fragment; + +import android.app.Dialog; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.graphics.Point; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.FrameLayout; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.google.android.material.bottomsheet.BottomSheetBehavior; +import com.google.android.material.bottomsheet.BottomSheetDialog; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import com.rs.macall.androidx.basemodel.callback.BaseRecycleBtnClickListener; +import com.rs.macall.androidx.basemodel.decoration.MyDividerItemDecoration; +import com.rs.macall.androidx.basemodel.utils.DimensionConvert; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.SmartRefreshLayoutHelp; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.listener.OnRefreshListener; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.databinding.FragmentWorkbenchAddBinding; +import com.ycgis.macall.personalcenter.m.adapterbean.AppInfoBean; +import com.ycgis.macall.personalcenter.m.adapterbean.WorkAppBean; +import com.ycgis.macall.personalcenter.m.provider.NativeAppProvider; +import com.ycgis.macall.personalcenter.m.requestbean.AppInfoModel; +import com.ycgis.macall.personalcenter.m.requestbean.BaseRequestModel; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.callback.OnFragmentOnClickListener; +import com.ycgis.macall.personalcenter.p.callback.WorkManageCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.CommonCompositeManage; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; +import com.ycgis.macall.personalcenter.v.adapter.WorkCustomAppAdapter; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/2 14:14 + * copyright: @ruansee.com + * Describe: + */ +public class WorkbenchManageFragment extends BottomSheetDialogFragment { + private FragmentWorkbenchAddBinding binding; + private WorkCustomAppAdapter appAdapter; + private WorkManageCallback clickListener; + private List selectPackageNames; + private List serverData; + private List addressData; + + public WorkbenchManageFragment() { + } + + public void setClickListener(WorkManageCallback clickListener) { + this.clickListener = clickListener; + } + + public void setSelectPackageNames(List selectPackageNames) { + this.selectPackageNames = selectPackageNames; + } + + @Override + public void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setStyle(STYLE_NORMAL, R.style.BottomSheetDialog); + } + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + binding = FragmentWorkbenchAddBinding.inflate(getLayoutInflater()); + init(); + return binding.getRoot(); + } + + private void init() { + SmartRefreshLayoutHelp.setPullDownToRefresh(getContext(), binding.workSrlAppList); + binding.workSrlAppList.setOnRefreshListener(refreshLayout -> getAppList()); + binding.workRvAppListAll.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); + MyDividerItemDecoration myDividerItemDecoration = new MyDividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL, 5); + myDividerItemDecoration.setBackground(R.color.colorGrey2); + binding.workRvAppListAll.addItemDecoration(myDividerItemDecoration); + getAppCenterData(); + } + + private void getAppList() { + List dataList = new ArrayList<>(); + WorkAppBean bean = new WorkAppBean(); + bean.setBaseType(0); + bean.setBaseMessage(""); + dataList.add(bean); + initData(dataList); + NativeAppProvider nativeAppProvider = new NativeAppProvider(getContext(), selectPackageNames); + nativeAppProvider.asyncCheckInstallApps(new BaseRequestCallback>() { + @Override + public void onRequestFailure(String msg) { + + } + + @Override + public void onRequestSuccess(List result) { + addressData = result; + hanData(); + } + }); + } + + private void hanData() { + if (addressData == null) return; + if (serverData == null) return; + List result = new ArrayList<>(); + for (int i = 0; i < addressData.size(); i++) { + WorkAppBean bean = addressData.get(i); + for (AppInfoBean b : serverData) { + //bean.getAppName().equals(b.getName()) && + if ( bean.getPackageName().equals(b.getPackageName())) { + result.add(bean); + break; + } + } + } + initData(result); + binding.workSrlAppList.finishRefresh(); + } + + private void initData(List dataList) { + if (appAdapter == null) { + appAdapter = new WorkCustomAppAdapter(getContext(), dataList); + binding.workRvAppListAll.setAdapter(appAdapter); + appAdapter.setBtnClickListener(new BaseRecycleBtnClickListener() { + @Override + public void onSingleClick(View v, int position, int what, Object msg) { + WorkAppBean dataItem = appAdapter.getDataItem(position); + if (what == 1) { + clickListener.onAdd(dataItem); + dataItem.setAdd(true); + } else { + clickListener.onRemove(dataItem); + dataItem.setAdd(false); + } + appAdapter.notifyItemChanged(position, 5); + } + }); + } else { + appAdapter.upData(dataList); + } + } + + /** + * 获取应用中心应用 + */ + private void getAppCenterData() { + ApiModel.request("getApplicationCenterData", + RetrofitService.getBaseInstance().applicationList(null, null, 1), + new BaseRequestCallback>>() { + @Override + public void onRequestFailure(String msg) { +// LogUtils.e("获取应用", msg); + ToastUtil.centered(getContext(),msg); + List dataList = new ArrayList<>(); + WorkAppBean bean = new WorkAppBean(); + bean.setBaseType(-1); + bean.setBaseMessage(msg); + dataList.add(bean); + initData(dataList); + binding.workSrlAppList.finishRefresh(); + } + + @Override + public void onRequestSuccess(BaseRequestModel> result) { +// LogUtils.e("获取应用", result.toString()); + if (result.getCode() == 20041) { + serverData = result.getData(); + hanData(); + }else { + ToastUtil.centered(getContext(),result.getMsg()); + List dataList = new ArrayList<>(); + WorkAppBean bean = new WorkAppBean(); + bean.setBaseType(-1); + bean.setBaseMessage(result.getMsg()); + dataList.add(bean); + initData(dataList); + binding.workSrlAppList.finishRefresh(); + } + } + }); + } + + @Override + public void onStart() { + super.onStart(); + // 设置软键盘不自动弹出 + getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); + BottomSheetDialog dialog = (BottomSheetDialog) getDialog(); + FrameLayout bottomSheet = dialog.getDelegate().findViewById(R.id.design_bottom_sheet); + if (bottomSheet != null) { + CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) bottomSheet.getLayoutParams(); + layoutParams.height = getHeight(); + BottomSheetBehavior from = BottomSheetBehavior.from(bottomSheet); +// behavior = BottomSheetBehavior.from(bottomSheet); + // 初始为展开状态 + from.setState(BottomSheetBehavior.STATE_EXPANDED); + } + binding.workSrlAppList.autoRefresh(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + CommonCompositeManage.getInstance().unDisposable("getApplicationCenterData"); + + } + + /** + * 获取屏幕高度 + * + * @return height + */ + private int getHeight() { + int height = 1920; + if (getContext() != null) { + WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); + Point point = new Point(); + if (wm != null) { + // 使用Point已经减去了状态栏高度 + wm.getDefaultDisplay().getSize(point); + height = point.y - DimensionConvert.dip2px(getContext(), 68); + } + } + return height; + } + + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/Compat.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/Compat.java new file mode 100644 index 0000000..3bd56eb --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/Compat.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright 2011, 2012 Chris Banes. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ +package com.ycgis.macall.personalcenter.v.photoview; + +import android.annotation.TargetApi; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.view.View; + +class Compat { + + private static final int SIXTY_FPS_INTERVAL = 1000 / 60; + + public static void postOnAnimation(View view, Runnable runnable) { + if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { + postOnAnimationJellyBean(view, runnable); + } else { + view.postDelayed(runnable, SIXTY_FPS_INTERVAL); + } + } + + @TargetApi(16) + private static void postOnAnimationJellyBean(View view, Runnable runnable) { + view.postOnAnimation(runnable); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/CustomGestureDetector.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/CustomGestureDetector.java new file mode 100644 index 0000000..ad53800 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/CustomGestureDetector.java @@ -0,0 +1,203 @@ +/******************************************************************************* + * Copyright 2011, 2012 Chris Banes. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ +package com.ycgis.macall.personalcenter.v.photoview; + +import android.content.Context; +import android.view.MotionEvent; +import android.view.ScaleGestureDetector; +import android.view.VelocityTracker; +import android.view.ViewConfiguration; + +/** + * Does a whole lot of gesture detecting. + */ +class CustomGestureDetector { + + private static final int INVALID_POINTER_ID = -1; + + private int mActivePointerId = INVALID_POINTER_ID; + private int mActivePointerIndex = 0; + private final ScaleGestureDetector mDetector; + + private VelocityTracker mVelocityTracker; + private boolean mIsDragging; + private float mLastTouchX; + private float mLastTouchY; + private final float mTouchSlop; + private final float mMinimumVelocity; + private OnGestureListener mListener; + + CustomGestureDetector(Context context, OnGestureListener listener) { + final ViewConfiguration configuration = ViewConfiguration + .get(context); + mMinimumVelocity = configuration.getScaledMinimumFlingVelocity(); + mTouchSlop = configuration.getScaledTouchSlop(); + + mListener = listener; + ScaleGestureDetector.OnScaleGestureListener mScaleListener = new ScaleGestureDetector.OnScaleGestureListener() { + + @Override + public boolean onScale(ScaleGestureDetector detector) { + float scaleFactor = detector.getScaleFactor(); + + if (Float.isNaN(scaleFactor) || Float.isInfinite(scaleFactor)) + return false; + + mListener.onScale(scaleFactor, + detector.getFocusX(), detector.getFocusY()); + return true; + } + + @Override + public boolean onScaleBegin(ScaleGestureDetector detector) { + return true; + } + + @Override + public void onScaleEnd(ScaleGestureDetector detector) { + // NO-OP + } + }; + mDetector = new ScaleGestureDetector(context, mScaleListener); + } + + private float getActiveX(MotionEvent ev) { + try { + return ev.getX(mActivePointerIndex); + } catch (Exception e) { + return ev.getX(); + } + } + + private float getActiveY(MotionEvent ev) { + try { + return ev.getY(mActivePointerIndex); + } catch (Exception e) { + return ev.getY(); + } + } + + public boolean isScaling() { + return mDetector.isInProgress(); + } + + public boolean isDragging() { + return mIsDragging; + } + + public boolean onTouchEvent(MotionEvent ev) { + try { + mDetector.onTouchEvent(ev); + return processTouchEvent(ev); + } catch (IllegalArgumentException e) { + // Fix for support lib bug, happening when onDestroy is called + return true; + } + } + + private boolean processTouchEvent(MotionEvent ev) { + final int action = ev.getAction(); + switch (action & MotionEvent.ACTION_MASK) { + case MotionEvent.ACTION_DOWN: + mActivePointerId = ev.getPointerId(0); + + mVelocityTracker = VelocityTracker.obtain(); + if (null != mVelocityTracker) { + mVelocityTracker.addMovement(ev); + } + + mLastTouchX = getActiveX(ev); + mLastTouchY = getActiveY(ev); + mIsDragging = false; + break; + case MotionEvent.ACTION_MOVE: + final float x = getActiveX(ev); + final float y = getActiveY(ev); + final float dx = x - mLastTouchX, dy = y - mLastTouchY; + + if (!mIsDragging) { + // Use Pythagoras to see if drag length is larger than + // touch slop + mIsDragging = Math.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop; + } + + if (mIsDragging) { + mListener.onDrag(dx, dy); + mLastTouchX = x; + mLastTouchY = y; + + if (null != mVelocityTracker) { + mVelocityTracker.addMovement(ev); + } + } + break; + case MotionEvent.ACTION_CANCEL: + mActivePointerId = INVALID_POINTER_ID; + // Recycle Velocity Tracker + if (null != mVelocityTracker) { + mVelocityTracker.recycle(); + mVelocityTracker = null; + } + break; + case MotionEvent.ACTION_UP: + mActivePointerId = INVALID_POINTER_ID; + if (mIsDragging) { + if (null != mVelocityTracker) { + mLastTouchX = getActiveX(ev); + mLastTouchY = getActiveY(ev); + + // Compute velocity within the last 1000ms + mVelocityTracker.addMovement(ev); + mVelocityTracker.computeCurrentVelocity(1000); + + final float vX = mVelocityTracker.getXVelocity(), vY = mVelocityTracker + .getYVelocity(); + + // If the velocity is greater than minVelocity, call + // listener + if (Math.max(Math.abs(vX), Math.abs(vY)) >= mMinimumVelocity) { + mListener.onFling(mLastTouchX, mLastTouchY, -vX, + -vY); + } + } + } + + // Recycle Velocity Tracker + if (null != mVelocityTracker) { + mVelocityTracker.recycle(); + mVelocityTracker = null; + } + break; + case MotionEvent.ACTION_POINTER_UP: + final int pointerIndex = Util.getPointerIndex(ev.getAction()); + final int pointerId = ev.getPointerId(pointerIndex); + if (pointerId == mActivePointerId) { + // This was our active pointer going up. Choose a new + // active pointer and adjust accordingly. + final int newPointerIndex = pointerIndex == 0 ? 1 : 0; + mActivePointerId = ev.getPointerId(newPointerIndex); + mLastTouchX = ev.getX(newPointerIndex); + mLastTouchY = ev.getY(newPointerIndex); + } + break; + } + + mActivePointerIndex = ev + .findPointerIndex(mActivePointerId != INVALID_POINTER_ID ? mActivePointerId + : 0); + return true; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnGestureListener.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnGestureListener.java new file mode 100644 index 0000000..361f9d1 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnGestureListener.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 2011, 2012 Chris Banes. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ +package com.ycgis.macall.personalcenter.v.photoview; + +interface OnGestureListener { + + void onDrag(float dx, float dy); + + void onFling(float startX, float startY, float velocityX, + float velocityY); + + void onScale(float scaleFactor, float focusX, float focusY); + +} \ No newline at end of file diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnMatrixChangedListener.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnMatrixChangedListener.java new file mode 100644 index 0000000..79b90d8 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnMatrixChangedListener.java @@ -0,0 +1,18 @@ +package com.ycgis.macall.personalcenter.v.photoview; + +import android.graphics.RectF; + +/** + * Interface definition for a callback to be invoked when the internal Matrix has changed for + * this View. + */ +public interface OnMatrixChangedListener { + + /** + * Callback for when the Matrix displaying the Drawable has changed. This could be because + * the View's bounds have changed, or the user has zoomed. + * + * @param rect - Rectangle displaying the Drawable's new bounds. + */ + void onMatrixChanged(RectF rect); +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnOutsidePhotoTapListener.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnOutsidePhotoTapListener.java new file mode 100644 index 0000000..eb18fdc --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnOutsidePhotoTapListener.java @@ -0,0 +1,14 @@ +package com.ycgis.macall.personalcenter.v.photoview; + +import android.widget.ImageView; + +/** + * Callback when the user tapped outside of the photo + */ +public interface OnOutsidePhotoTapListener { + + /** + * The outside of the photo has been tapped + */ + void onOutsidePhotoTap(ImageView imageView); +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnPhotoTapListener.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnPhotoTapListener.java new file mode 100644 index 0000000..6b31810 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnPhotoTapListener.java @@ -0,0 +1,23 @@ +package com.ycgis.macall.personalcenter.v.photoview; + +import android.widget.ImageView; + +/** + * A callback to be invoked when the Photo is tapped with a single + * tap. + */ +public interface OnPhotoTapListener { + + /** + * A callback to receive where the user taps on a photo. You will only receive a callback if + * the user taps on the actual photo, tapping on 'whitespace' will be ignored. + * + * @param view ImageView the user tapped. + * @param x where the user tapped from the of the Drawable, as percentage of the + * Drawable width. + * @param y where the user tapped from the top of the Drawable, as percentage of the + * Drawable height. + */ + void onPhotoTap(ImageView view, float x, float y); + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnScaleChangedListener.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnScaleChangedListener.java new file mode 100644 index 0000000..065620f --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnScaleChangedListener.java @@ -0,0 +1,17 @@ +package com.ycgis.macall.personalcenter.v.photoview; + + +/** + * Interface definition for callback to be invoked when attached ImageView scale changes + */ +public interface OnScaleChangedListener { + + /** + * Callback for when the scale changes + * + * @param scaleFactor the scale factor (less than 1 for zoom out, greater than 1 for zoom in) + * @param focusX focal point X position + * @param focusY focal point Y position + */ + void onScaleChange(float scaleFactor, float focusX, float focusY); +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnSingleFlingListener.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnSingleFlingListener.java new file mode 100644 index 0000000..a6d16dc --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnSingleFlingListener.java @@ -0,0 +1,21 @@ +package com.ycgis.macall.personalcenter.v.photoview; + +import android.view.MotionEvent; + +/** + * A callback to be invoked when the ImageView is flung with a single + * touch + */ +public interface OnSingleFlingListener { + + /** + * A callback to receive where the user flings on a ImageView. You will receive a callback if + * the user flings anywhere on the view. + * + * @param e1 MotionEvent the user first touch. + * @param e2 MotionEvent the user last touch. + * @param velocityX distance of user's horizontal fling. + * @param velocityY distance of user's vertical fling. + */ + boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY); +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnViewDragListener.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnViewDragListener.java new file mode 100644 index 0000000..a709982 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnViewDragListener.java @@ -0,0 +1,16 @@ +package com.ycgis.macall.personalcenter.v.photoview; + +/** + * Interface definition for a callback to be invoked when the photo is experiencing a drag event + */ +public interface OnViewDragListener { + + /** + * Callback for when the photo is experiencing a drag event. This cannot be invoked when the + * user is scaling. + * + * @param dx The change of the coordinates in the x-direction + * @param dy The change of the coordinates in the y-direction + */ + void onDrag(float dx, float dy); +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnViewTapListener.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnViewTapListener.java new file mode 100644 index 0000000..d851ac4 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/OnViewTapListener.java @@ -0,0 +1,16 @@ +package com.ycgis.macall.personalcenter.v.photoview; + +import android.view.View; + +public interface OnViewTapListener { + + /** + * A callback to receive where the user taps on a ImageView. You will receive a callback if + * the user taps anywhere on the view, tapping on 'whitespace' will not be ignored. + * + * @param view - View the user tapped. + * @param x - where the user tapped from the left of the View. + * @param y - where the user tapped from the top of the View. + */ + void onViewTap(View view, float x, float y); +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/PhotoView.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/PhotoView.java new file mode 100644 index 0000000..4274507 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/PhotoView.java @@ -0,0 +1,265 @@ +/******************************************************************************* + * Copyright 2011, 2012 Chris Banes. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ +package com.ycgis.macall.personalcenter.v.photoview; + +import android.content.Context; +import android.graphics.Matrix; +import android.graphics.RectF; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.util.AttributeSet; +import android.view.GestureDetector; +import android.widget.ImageView; + +/** + * A zoomable {@link ImageView}. See {@link PhotoViewAttacher} for most of the details on how the zooming + * is accomplished + */ +public class PhotoView extends androidx.appcompat.widget.AppCompatImageView { + + private PhotoViewAttacher attacher; + private ScaleType pendingScaleType; + + public PhotoView(Context context) { + this(context, null); + } + + public PhotoView(Context context, AttributeSet attr) { + this(context, attr, 0); + } + + public PhotoView(Context context, AttributeSet attr, int defStyle) { + super(context, attr, defStyle); + init(); + } + +// @TargetApi(21) +// public PhotoView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { +// super(context, attrs, defStyleAttr, defStyleRes); +// init(); +// } + + private void init() { + attacher = new PhotoViewAttacher(this); + //We always pose as a Matrix scale type, though we can change to another scale type + //via the attacher + super.setScaleType(ScaleType.MATRIX); + //apply the previously applied scale type + if (pendingScaleType != null) { + setScaleType(pendingScaleType); + pendingScaleType = null; + } + } + + /** + * Get the current {@link PhotoViewAttacher} for this view. Be wary of holding on to references + * to this attacher, as it has a reference to this view, which, if a reference is held in the + * wrong place, can cause memory leaks. + * + * @return the attacher. + */ + public PhotoViewAttacher getAttacher() { + return attacher; + } + + @Override + public ScaleType getScaleType() { + return attacher.getScaleType(); + } + + @Override + public Matrix getImageMatrix() { + return attacher.getImageMatrix(); + } + + @Override + public void setOnLongClickListener(OnLongClickListener l) { + attacher.setOnLongClickListener(l); + } + + @Override + public void setOnClickListener(OnClickListener l) { + attacher.setOnClickListener(l); + } + + @Override + public void setScaleType(ScaleType scaleType) { + if (attacher == null) { + pendingScaleType = scaleType; + } else { + attacher.setScaleType(scaleType); + } + } + + @Override + public void setImageDrawable(Drawable drawable) { + super.setImageDrawable(drawable); + // setImageBitmap calls through to this method + if (attacher != null) { + attacher.update(); + } + } + + @Override + public void setImageResource(int resId) { + super.setImageResource(resId); + if (attacher != null) { + attacher.update(); + } + } + + @Override + public void setImageURI(Uri uri) { + super.setImageURI(uri); + if (attacher != null) { + attacher.update(); + } + } + + @Override + protected boolean setFrame(int l, int t, int r, int b) { + boolean changed = super.setFrame(l, t, r, b); + if (changed) { + attacher.update(); + } + return changed; + } + + public void setRotationTo(float rotationDegree) { + attacher.setRotationTo(rotationDegree); + } + + public void setRotationBy(float rotationDegree) { + attacher.setRotationBy(rotationDegree); + } + + @Deprecated + public boolean isZoomEnabled() { + return attacher.isZoomEnabled(); + } + + public boolean isZoomable() { + return attacher.isZoomable(); + } + + public void setZoomable(boolean zoomable) { + attacher.setZoomable(zoomable); + } + + public RectF getDisplayRect() { + return attacher.getDisplayRect(); + } + + public void getDisplayMatrix(Matrix matrix) { + attacher.getDisplayMatrix(matrix); + } + + public boolean setDisplayMatrix(Matrix finalRectangle) { + return attacher.setDisplayMatrix(finalRectangle); + } + + public void getSuppMatrix(Matrix matrix) { + attacher.getSuppMatrix(matrix); + } + + public boolean setSuppMatrix(Matrix matrix) { + return attacher.setDisplayMatrix(matrix); + } + + public float getMinimumScale() { + return attacher.getMinimumScale(); + } + + public float getMediumScale() { + return attacher.getMediumScale(); + } + + public float getMaximumScale() { + return attacher.getMaximumScale(); + } + + public float getScale() { + return attacher.getScale(); + } + + public void setAllowParentInterceptOnEdge(boolean allow) { + attacher.setAllowParentInterceptOnEdge(allow); + } + + public void setMinimumScale(float minimumScale) { + attacher.setMinimumScale(minimumScale); + } + + public void setMediumScale(float mediumScale) { + attacher.setMediumScale(mediumScale); + } + + public void setMaximumScale(float maximumScale) { + attacher.setMaximumScale(maximumScale); + } + + public void setScaleLevels(float minimumScale, float mediumScale, float maximumScale) { + attacher.setScaleLevels(minimumScale, mediumScale, maximumScale); + } + + public void setOnMatrixChangeListener(OnMatrixChangedListener listener) { + attacher.setOnMatrixChangeListener(listener); + } + + public void setOnPhotoTapListener(OnPhotoTapListener listener) { + attacher.setOnPhotoTapListener(listener); + } + + public void setOnOutsidePhotoTapListener(OnOutsidePhotoTapListener listener) { + attacher.setOnOutsidePhotoTapListener(listener); + } + + public void setOnViewTapListener(OnViewTapListener listener) { + attacher.setOnViewTapListener(listener); + } + + public void setOnViewDragListener(OnViewDragListener listener) { + attacher.setOnViewDragListener(listener); + } + + public void setScale(float scale) { + attacher.setScale(scale); + } + + public void setScale(float scale, boolean animate) { + attacher.setScale(scale, animate); + } + + public void setScale(float scale, float focalX, float focalY, boolean animate) { + attacher.setScale(scale, focalX, focalY, animate); + } + + public void setZoomTransitionDuration(int milliseconds) { + attacher.setZoomTransitionDuration(milliseconds); + } + + public void setOnDoubleTapListener(GestureDetector.OnDoubleTapListener onDoubleTapListener) { + attacher.setOnDoubleTapListener(onDoubleTapListener); + } + + public void setOnScaleChangeListener(OnScaleChangedListener onScaleChangedListener) { + attacher.setOnScaleChangeListener(onScaleChangedListener); + } + + public void setOnSingleFlingListener(OnSingleFlingListener onSingleFlingListener) { + attacher.setOnSingleFlingListener(onSingleFlingListener); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/PhotoViewAdapter.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/PhotoViewAdapter.java new file mode 100644 index 0000000..6285657 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/PhotoViewAdapter.java @@ -0,0 +1,60 @@ +package com.ycgis.macall.personalcenter.v.photoview; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.rs.macall.androidx.basemodel.base.BaseRecyclerAdapter; +import com.ycgis.macall.personalcenter.R; + +import java.util.List; + +/** + * @Author macall + * @Create 2019/12/12 0012 + * @Describe + */ +public class PhotoViewAdapter extends BaseRecyclerAdapter { + + public PhotoViewAdapter(Context context, List dataList) { + super(context, dataList); + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { + View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.photo_view_layout,viewGroup,false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) { + Bitmap bitmap = BitmapFactory.decodeFile(getDataItem(i)); + if (bitmap!= null){ + viewHolder.iv_photo.setImageBitmap(bitmap); + } + } + + public class ViewHolder extends BaseRecyclerAdapter.ViewHolder{ + private PhotoView iv_photo; + + public ViewHolder(View itemView) { + super(itemView); + iv_photo = (PhotoView) itemView; + iv_photo.setZoomTransitionDuration(500); + if (listClickListener != null){ + itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + listClickListener.onItemClickListener(v,getAdapterPosition()); + } + }); + } + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/PhotoViewAttacher.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/PhotoViewAttacher.java new file mode 100644 index 0000000..70f6abe --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/PhotoViewAttacher.java @@ -0,0 +1,864 @@ +/******************************************************************************* + * Copyright 2011, 2012 Chris Banes. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ +package com.ycgis.macall.personalcenter.v.photoview; + +import android.content.Context; +import android.graphics.Matrix; +import android.graphics.Matrix.ScaleToFit; +import android.graphics.RectF; +import android.graphics.drawable.Drawable; +import android.view.GestureDetector; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnLongClickListener; +import android.view.ViewParent; +import android.view.animation.AccelerateDecelerateInterpolator; +import android.view.animation.Interpolator; +import android.widget.ImageView; +import android.widget.ImageView.ScaleType; +import android.widget.OverScroller; + +import androidx.core.view.MotionEventCompat; + +/** + * The component of {@link PhotoView} which does the work allowing for zooming, scaling, panning, etc. + * It is made public in case you need to subclass something other than {@link ImageView} and still + * gain the functionality that {@link PhotoView} offers + */ +public class PhotoViewAttacher implements View.OnTouchListener, + View.OnLayoutChangeListener { + + private static float DEFAULT_MAX_SCALE = 3.0f; + private static float DEFAULT_MID_SCALE = 1.75f; + private static float DEFAULT_MIN_SCALE = 1.0f; + private static int DEFAULT_ZOOM_DURATION = 200; + + private static final int EDGE_NONE = -1; + private static final int EDGE_LEFT = 0; + private static final int EDGE_RIGHT = 1; + private static final int EDGE_BOTH = 2; + private static int SINGLE_TOUCH = 1; + + private Interpolator mInterpolator = new AccelerateDecelerateInterpolator(); + private int mZoomDuration = DEFAULT_ZOOM_DURATION; + private float mMinScale = DEFAULT_MIN_SCALE; + private float mMidScale = DEFAULT_MID_SCALE; + private float mMaxScale = DEFAULT_MAX_SCALE; + + private boolean mAllowParentInterceptOnEdge = true; + private boolean mBlockParentIntercept = false; + + private ImageView mImageView; + + // Gesture Detectors + private GestureDetector mGestureDetector; + private CustomGestureDetector mScaleDragDetector; + + // These are set so we don't keep allocating them on the heap + private final Matrix mBaseMatrix = new Matrix(); + private final Matrix mDrawMatrix = new Matrix(); + private final Matrix mSuppMatrix = new Matrix(); + private final RectF mDisplayRect = new RectF(); + private final float[] mMatrixValues = new float[9]; + + // Listeners + private OnMatrixChangedListener mMatrixChangeListener; + private OnPhotoTapListener mPhotoTapListener; + private OnOutsidePhotoTapListener mOutsidePhotoTapListener; + private OnViewTapListener mViewTapListener; + private View.OnClickListener mOnClickListener; + private OnLongClickListener mLongClickListener; + private OnScaleChangedListener mScaleChangeListener; + private OnSingleFlingListener mSingleFlingListener; + private OnViewDragListener mOnViewDragListener; + + private FlingRunnable mCurrentFlingRunnable; + private int mScrollEdge = EDGE_BOTH; + private float mBaseRotation; + + private boolean mZoomEnabled = true; + private ScaleType mScaleType = ScaleType.FIT_CENTER; + + private OnGestureListener onGestureListener = new OnGestureListener() { + @Override + public void onDrag(float dx, float dy) { + if (mScaleDragDetector.isScaling()) { + return; // Do not drag if we are already scaling + } + + if (mOnViewDragListener != null) { + mOnViewDragListener.onDrag(dx, dy); + } + mSuppMatrix.postTranslate(dx, dy); + checkAndDisplayMatrix(); + + /* + * Here we decide whether to let the ImageView's parent to start taking + * over the touch event. + * + * First we check whether this function is enabled. We never want the + * parent to take over if we're scaling. We then check the edge we're + * on, and the direction of the scroll (i.e. if we're pulling against + * the edge, aka 'overscrolling', let the parent take over). + */ + ViewParent parent = mImageView.getParent(); + if (mAllowParentInterceptOnEdge && !mScaleDragDetector.isScaling() && !mBlockParentIntercept) { + if (mScrollEdge == EDGE_BOTH + || (mScrollEdge == EDGE_LEFT && dx >= 1f) + || (mScrollEdge == EDGE_RIGHT && dx <= -1f)) { + if (parent != null) { + parent.requestDisallowInterceptTouchEvent(false); + } + } + } else { + if (parent != null) { + parent.requestDisallowInterceptTouchEvent(true); + } + } + } + + @Override + public void onFling(float startX, float startY, float velocityX, float velocityY) { + mCurrentFlingRunnable = new FlingRunnable(mImageView.getContext()); + mCurrentFlingRunnable.fling(getImageViewWidth(mImageView), + getImageViewHeight(mImageView), (int) velocityX, (int) velocityY); + mImageView.post(mCurrentFlingRunnable); + } + + @Override + public void onScale(float scaleFactor, float focusX, float focusY) { + if ((getScale() < mMaxScale || scaleFactor < 1f) && (getScale() > mMinScale || scaleFactor > 1f)) { + if (mScaleChangeListener != null) { + mScaleChangeListener.onScaleChange(scaleFactor, focusX, focusY); + } + mSuppMatrix.postScale(scaleFactor, scaleFactor, focusX, focusY); + checkAndDisplayMatrix(); + } + } + }; + + public PhotoViewAttacher(ImageView imageView) { + mImageView = imageView; + imageView.setOnTouchListener(this); + imageView.addOnLayoutChangeListener(this); + + if (imageView.isInEditMode()) { + return; + } + + mBaseRotation = 0.0f; + + // Create Gesture Detectors... + mScaleDragDetector = new CustomGestureDetector(imageView.getContext(), onGestureListener); + + mGestureDetector = new GestureDetector(imageView.getContext(), new GestureDetector.SimpleOnGestureListener() { + + // forward long click listener + @Override + public void onLongPress(MotionEvent e) { + if (mLongClickListener != null) { + mLongClickListener.onLongClick(mImageView); + } + } + + @Override + public boolean onFling(MotionEvent e1, MotionEvent e2, + float velocityX, float velocityY) { + if (mSingleFlingListener != null) { + if (getScale() > DEFAULT_MIN_SCALE) { + return false; + } + + if (MotionEventCompat.getPointerCount(e1) > SINGLE_TOUCH + || MotionEventCompat.getPointerCount(e2) > SINGLE_TOUCH) { + return false; + } + + return mSingleFlingListener.onFling(e1, e2, velocityX, velocityY); + } + return false; + } + }); + + mGestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() { + @Override + public boolean onSingleTapConfirmed(MotionEvent e) { + if (mOnClickListener != null) { + mOnClickListener.onClick(mImageView); + } + final RectF displayRect = getDisplayRect(); + + final float x = e.getX(), y = e.getY(); + + if (mViewTapListener != null) { + mViewTapListener.onViewTap(mImageView, x, y); + } + + if (displayRect != null) { + + // Check to see if the user tapped on the photo + if (displayRect.contains(x, y)) { + + float xResult = (x - displayRect.left) + / displayRect.width(); + float yResult = (y - displayRect.top) + / displayRect.height(); + + if (mPhotoTapListener != null) { + mPhotoTapListener.onPhotoTap(mImageView, xResult, yResult); + } + return true; + } else { + if (mOutsidePhotoTapListener != null) { + mOutsidePhotoTapListener.onOutsidePhotoTap(mImageView); + } + } + } + return false; + } + + @Override + public boolean onDoubleTap(MotionEvent ev) { + try { + float scale = getScale(); + float x = ev.getX(); + float y = ev.getY(); + + if (scale < getMediumScale()) { + setScale(getMediumScale(), x, y, true); + } else if (scale >= getMediumScale() && scale < getMaximumScale()) { + setScale(getMaximumScale(), x, y, true); + } else { + setScale(getMinimumScale(), x, y, true); + } + } catch (ArrayIndexOutOfBoundsException e) { + // Can sometimes happen when getX() and getY() is called + } + + return true; + } + + @Override + public boolean onDoubleTapEvent(MotionEvent e) { + // Wait for the confirmed onDoubleTap() instead + return false; + } + }); + } + + public void setOnDoubleTapListener(GestureDetector.OnDoubleTapListener newOnDoubleTapListener) { + this.mGestureDetector.setOnDoubleTapListener(newOnDoubleTapListener); + } + + public void setOnScaleChangeListener(OnScaleChangedListener onScaleChangeListener) { + this.mScaleChangeListener = onScaleChangeListener; + } + + public void setOnSingleFlingListener(OnSingleFlingListener onSingleFlingListener) { + this.mSingleFlingListener = onSingleFlingListener; + } + + @Deprecated + public boolean isZoomEnabled() { + return mZoomEnabled; + } + + public RectF getDisplayRect() { + checkMatrixBounds(); + return getDisplayRect(getDrawMatrix()); + } + + public boolean setDisplayMatrix(Matrix finalMatrix) { + if (finalMatrix == null) { + throw new IllegalArgumentException("Matrix cannot be null"); + } + + if (mImageView.getDrawable() == null) { + return false; + } + + mSuppMatrix.set(finalMatrix); + checkAndDisplayMatrix(); + + return true; + } + + public void setBaseRotation(final float degrees) { + mBaseRotation = degrees % 360; + update(); + setRotationBy(mBaseRotation); + checkAndDisplayMatrix(); + } + + public void setRotationTo(float degrees) { + mSuppMatrix.setRotate(degrees % 360); + checkAndDisplayMatrix(); + } + + public void setRotationBy(float degrees) { + mSuppMatrix.postRotate(degrees % 360); + checkAndDisplayMatrix(); + } + + public float getMinimumScale() { + return mMinScale; + } + + public float getMediumScale() { + return mMidScale; + } + + public float getMaximumScale() { + return mMaxScale; + } + + public float getScale() { + return (float) Math.sqrt((float) Math.pow(getValue(mSuppMatrix, Matrix.MSCALE_X), 2) + (float) Math.pow(getValue(mSuppMatrix, Matrix.MSKEW_Y), 2)); + } + + public ScaleType getScaleType() { + return mScaleType; + } + + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { + // Update our base matrix, as the bounds have changed + if (left != oldLeft || top != oldTop || right != oldRight || bottom != oldBottom) { + updateBaseMatrix(mImageView.getDrawable()); + } + } + + @Override + public boolean onTouch(View v, MotionEvent ev) { + boolean handled = false; + + if (mZoomEnabled && Util.hasDrawable((ImageView) v)) { + switch (ev.getAction()) { + case MotionEvent.ACTION_DOWN: + ViewParent parent = v.getParent(); + // First, disable the Parent from intercepting the touch + // event + if (parent != null) { + parent.requestDisallowInterceptTouchEvent(true); + } + + // If we're flinging, and the user presses down, cancel + // fling + cancelFling(); + break; + + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + // If the user has zoomed less than min scale, zoom back + // to min scale + if (getScale() < mMinScale) { + RectF rect = getDisplayRect(); + if (rect != null) { + v.post(new AnimatedZoomRunnable(getScale(), mMinScale, + rect.centerX(), rect.centerY())); + handled = true; + } + } else if (getScale() > mMaxScale) { + RectF rect = getDisplayRect(); + if (rect != null) { + v.post(new AnimatedZoomRunnable(getScale(), mMaxScale, + rect.centerX(), rect.centerY())); + handled = true; + } + } + break; + } + + // Try the Scale/Drag detector + if (mScaleDragDetector != null) { + boolean wasScaling = mScaleDragDetector.isScaling(); + boolean wasDragging = mScaleDragDetector.isDragging(); + + handled = mScaleDragDetector.onTouchEvent(ev); + + boolean didntScale = !wasScaling && !mScaleDragDetector.isScaling(); + boolean didntDrag = !wasDragging && !mScaleDragDetector.isDragging(); + + mBlockParentIntercept = didntScale && didntDrag; + } + + // Check to see if the user double tapped + if (mGestureDetector != null && mGestureDetector.onTouchEvent(ev)) { + handled = true; + } + + } + + return handled; + } + + public void setAllowParentInterceptOnEdge(boolean allow) { + mAllowParentInterceptOnEdge = allow; + } + + public void setMinimumScale(float minimumScale) { + Util.checkZoomLevels(minimumScale, mMidScale, mMaxScale); + mMinScale = minimumScale; + } + + public void setMediumScale(float mediumScale) { + Util.checkZoomLevels(mMinScale, mediumScale, mMaxScale); + mMidScale = mediumScale; + } + + public void setMaximumScale(float maximumScale) { + Util.checkZoomLevels(mMinScale, mMidScale, maximumScale); + mMaxScale = maximumScale; + } + + public void setScaleLevels(float minimumScale, float mediumScale, float maximumScale) { + Util.checkZoomLevels(minimumScale, mediumScale, maximumScale); + mMinScale = minimumScale; + mMidScale = mediumScale; + mMaxScale = maximumScale; + } + + public void setOnLongClickListener(OnLongClickListener listener) { + mLongClickListener = listener; + } + + public void setOnClickListener(View.OnClickListener listener) { + mOnClickListener = listener; + } + + public void setOnMatrixChangeListener(OnMatrixChangedListener listener) { + mMatrixChangeListener = listener; + } + + public void setOnPhotoTapListener(OnPhotoTapListener listener) { + mPhotoTapListener = listener; + } + + public void setOnOutsidePhotoTapListener(OnOutsidePhotoTapListener mOutsidePhotoTapListener) { + this.mOutsidePhotoTapListener = mOutsidePhotoTapListener; + } + + public void setOnViewTapListener(OnViewTapListener listener) { + mViewTapListener = listener; + } + + public void setOnViewDragListener(OnViewDragListener listener) { + mOnViewDragListener = listener; + } + + public void setScale(float scale) { + setScale(scale, false); + } + + public void setScale(float scale, boolean animate) { + setScale(scale, + (mImageView.getRight()) / 2, + (mImageView.getBottom()) / 2, + animate); + } + + public void setScale(float scale, float focalX, float focalY, + boolean animate) { + // Check to see if the scale is within bounds + if (scale < mMinScale || scale > mMaxScale) { + throw new IllegalArgumentException("Scale must be within the range of minScale and maxScale"); + } + + if (animate) { + mImageView.post(new AnimatedZoomRunnable(getScale(), scale, + focalX, focalY)); + } else { + mSuppMatrix.setScale(scale, scale, focalX, focalY); + checkAndDisplayMatrix(); + } + } + + /** + * Set the zoom interpolator + * + * @param interpolator the zoom interpolator + */ + public void setZoomInterpolator(Interpolator interpolator) { + mInterpolator = interpolator; + } + + public void setScaleType(ScaleType scaleType) { + if (Util.isSupportedScaleType(scaleType) && scaleType != mScaleType) { + mScaleType = scaleType; + update(); + } + } + + public boolean isZoomable() { + return mZoomEnabled; + } + + public void setZoomable(boolean zoomable) { + mZoomEnabled = zoomable; + update(); + } + + public void update() { + if (mZoomEnabled) { + // Update the base matrix using the current drawable + updateBaseMatrix(mImageView.getDrawable()); + } else { + // Reset the Matrix... + resetMatrix(); + } + } + + /** + * Get the display matrix + * + * @param matrix target matrix to copy to + */ + public void getDisplayMatrix(Matrix matrix) { + matrix.set(getDrawMatrix()); + } + + /** + * Get the current support matrix + */ + public void getSuppMatrix(Matrix matrix) { + matrix.set(mSuppMatrix); + } + + private Matrix getDrawMatrix() { + mDrawMatrix.set(mBaseMatrix); + mDrawMatrix.postConcat(mSuppMatrix); + return mDrawMatrix; + } + + public Matrix getImageMatrix() { + return mDrawMatrix; + } + + public void setZoomTransitionDuration(int milliseconds) { + this.mZoomDuration = milliseconds; + } + + /** + * Helper method that 'unpacks' a Matrix and returns the required value + * + * @param matrix Matrix to unpack + * @param whichValue Which value from Matrix.M* to return + * @return returned value + */ + private float getValue(Matrix matrix, int whichValue) { + matrix.getValues(mMatrixValues); + return mMatrixValues[whichValue]; + } + + /** + * Resets the Matrix back to FIT_CENTER, and then displays its contents + */ + private void resetMatrix() { + mSuppMatrix.reset(); + setRotationBy(mBaseRotation); + setImageViewMatrix(getDrawMatrix()); + checkMatrixBounds(); + } + + private void setImageViewMatrix(Matrix matrix) { + mImageView.setImageMatrix(matrix); + + // Call MatrixChangedListener if needed + if (mMatrixChangeListener != null) { + RectF displayRect = getDisplayRect(matrix); + if (displayRect != null) { + mMatrixChangeListener.onMatrixChanged(displayRect); + } + } + } + + /** + * Helper method that simply checks the Matrix, and then displays the result + */ + private void checkAndDisplayMatrix() { + if (checkMatrixBounds()) { + setImageViewMatrix(getDrawMatrix()); + } + } + + /** + * Helper method that maps the supplied Matrix to the current Drawable + * + * @param matrix - Matrix to map Drawable against + * @return RectF - Displayed Rectangle + */ + private RectF getDisplayRect(Matrix matrix) { + Drawable d = mImageView.getDrawable(); + if (d != null) { + mDisplayRect.set(0, 0, d.getIntrinsicWidth(), + d.getIntrinsicHeight()); + matrix.mapRect(mDisplayRect); + return mDisplayRect; + } + return null; + } + + /** + * Calculate Matrix for FIT_CENTER + * + * @param drawable - Drawable being displayed + */ + private void updateBaseMatrix(Drawable drawable) { + if (drawable == null) { + return; + } + + final float viewWidth = getImageViewWidth(mImageView); + final float viewHeight = getImageViewHeight(mImageView); + final int drawableWidth = drawable.getIntrinsicWidth(); + final int drawableHeight = drawable.getIntrinsicHeight(); + + mBaseMatrix.reset(); + + final float widthScale = viewWidth / drawableWidth; + final float heightScale = viewHeight / drawableHeight; + + if (mScaleType == ScaleType.CENTER) { + mBaseMatrix.postTranslate((viewWidth - drawableWidth) / 2F, + (viewHeight - drawableHeight) / 2F); + + } else if (mScaleType == ScaleType.CENTER_CROP) { + float scale = Math.max(widthScale, heightScale); + mBaseMatrix.postScale(scale, scale); + mBaseMatrix.postTranslate((viewWidth - drawableWidth * scale) / 2F, + (viewHeight - drawableHeight * scale) / 2F); + + } else if (mScaleType == ScaleType.CENTER_INSIDE) { + float scale = Math.min(1.0f, Math.min(widthScale, heightScale)); + mBaseMatrix.postScale(scale, scale); + mBaseMatrix.postTranslate((viewWidth - drawableWidth * scale) / 2F, + (viewHeight - drawableHeight * scale) / 2F); + + } else { + RectF mTempSrc = new RectF(0, 0, drawableWidth, drawableHeight); + RectF mTempDst = new RectF(0, 0, viewWidth, viewHeight); + + if ((int) mBaseRotation % 180 != 0) { + mTempSrc = new RectF(0, 0, drawableHeight, drawableWidth); + } + + switch (mScaleType) { + case FIT_CENTER: + mBaseMatrix.setRectToRect(mTempSrc, mTempDst, ScaleToFit.CENTER); + break; + + case FIT_START: + mBaseMatrix.setRectToRect(mTempSrc, mTempDst, ScaleToFit.START); + break; + + case FIT_END: + mBaseMatrix.setRectToRect(mTempSrc, mTempDst, ScaleToFit.END); + break; + + case FIT_XY: + mBaseMatrix.setRectToRect(mTempSrc, mTempDst, ScaleToFit.FILL); + break; + + default: + break; + } + } + + resetMatrix(); + } + + private boolean checkMatrixBounds() { + + final RectF rect = getDisplayRect(getDrawMatrix()); + if (rect == null) { + return false; + } + + final float height = rect.height(), width = rect.width(); + float deltaX = 0, deltaY = 0; + + final int viewHeight = getImageViewHeight(mImageView); + if (height <= viewHeight) { + switch (mScaleType) { + case FIT_START: + deltaY = -rect.top; + break; + case FIT_END: + deltaY = viewHeight - height - rect.top; + break; + default: + deltaY = (viewHeight - height) / 2 - rect.top; + break; + } + } else if (rect.top > 0) { + deltaY = -rect.top; + } else if (rect.bottom < viewHeight) { + deltaY = viewHeight - rect.bottom; + } + + final int viewWidth = getImageViewWidth(mImageView); + if (width <= viewWidth) { + switch (mScaleType) { + case FIT_START: + deltaX = -rect.left; + break; + case FIT_END: + deltaX = viewWidth - width - rect.left; + break; + default: + deltaX = (viewWidth - width) / 2 - rect.left; + break; + } + mScrollEdge = EDGE_BOTH; + } else if (rect.left > 0) { + mScrollEdge = EDGE_LEFT; + deltaX = -rect.left; + } else if (rect.right < viewWidth) { + deltaX = viewWidth - rect.right; + mScrollEdge = EDGE_RIGHT; + } else { + mScrollEdge = EDGE_NONE; + } + + // Finally actually translate the matrix + mSuppMatrix.postTranslate(deltaX, deltaY); + return true; + } + + private int getImageViewWidth(ImageView imageView) { + return imageView.getWidth() - imageView.getPaddingLeft() - imageView.getPaddingRight(); + } + + private int getImageViewHeight(ImageView imageView) { + return imageView.getHeight() - imageView.getPaddingTop() - imageView.getPaddingBottom(); + } + + private void cancelFling() { + if (mCurrentFlingRunnable != null) { + mCurrentFlingRunnable.cancelFling(); + mCurrentFlingRunnable = null; + } + } + + private class AnimatedZoomRunnable implements Runnable { + + private final float mFocalX, mFocalY; + private final long mStartTime; + private final float mZoomStart, mZoomEnd; + + public AnimatedZoomRunnable(final float currentZoom, final float targetZoom, + final float focalX, final float focalY) { + mFocalX = focalX; + mFocalY = focalY; + mStartTime = System.currentTimeMillis(); + mZoomStart = currentZoom; + mZoomEnd = targetZoom; + } + + @Override + public void run() { + + float t = interpolate(); + float scale = mZoomStart + t * (mZoomEnd - mZoomStart); + float deltaScale = scale / getScale(); + + onGestureListener.onScale(deltaScale, mFocalX, mFocalY); + + // We haven't hit our target scale yet, so post ourselves again + if (t < 1f) { + Compat.postOnAnimation(mImageView, this); + } + } + + private float interpolate() { + float t = 1f * (System.currentTimeMillis() - mStartTime) / mZoomDuration; + t = Math.min(1f, t); + t = mInterpolator.getInterpolation(t); + return t; + } + } + + private class FlingRunnable implements Runnable { + + private final OverScroller mScroller; + private int mCurrentX, mCurrentY; + + public FlingRunnable(Context context) { + mScroller = new OverScroller(context); + } + + public void cancelFling() { + mScroller.forceFinished(true); + } + + public void fling(int viewWidth, int viewHeight, int velocityX, + int velocityY) { + final RectF rect = getDisplayRect(); + if (rect == null) { + return; + } + + final int startX = Math.round(-rect.left); + final int minX, maxX, minY, maxY; + + if (viewWidth < rect.width()) { + minX = 0; + maxX = Math.round(rect.width() - viewWidth); + } else { + minX = maxX = startX; + } + + final int startY = Math.round(-rect.top); + if (viewHeight < rect.height()) { + minY = 0; + maxY = Math.round(rect.height() - viewHeight); + } else { + minY = maxY = startY; + } + + mCurrentX = startX; + mCurrentY = startY; + + // If we actually can move, fling the scroller + if (startX != maxX || startY != maxY) { + mScroller.fling(startX, startY, velocityX, velocityY, minX, + maxX, minY, maxY, 0, 0); + } + } + + @Override + public void run() { + if (mScroller.isFinished()) { + return; // remaining post that should not be handled + } + + if (mScroller.computeScrollOffset()) { + + final int newX = mScroller.getCurrX(); + final int newY = mScroller.getCurrY(); + + mSuppMatrix.postTranslate(mCurrentX - newX, mCurrentY - newY); + checkAndDisplayMatrix(); + + mCurrentX = newX; + mCurrentY = newY; + + // Post On animation + Compat.postOnAnimation(mImageView, this); + } + } + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/ShowPhotoDialog.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/ShowPhotoDialog.java new file mode 100644 index 0000000..085933d --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/ShowPhotoDialog.java @@ -0,0 +1,90 @@ +package com.ycgis.macall.personalcenter.v.photoview; + +import android.app.Dialog; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.view.Gravity; +import android.view.View; +import android.view.WindowManager; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.request.RequestOptions; +import com.ycgis.macall.personalcenter.R; + +/** + * @Author macall + * @Create 2020/5/19 0019 + * @Describe + */ +public class ShowPhotoDialog extends Dialog { + + public ShowPhotoDialog(@NonNull Context context) { + super(context); + } + + public ShowPhotoDialog(@NonNull Context context, int themeResId) { + super(context, themeResId); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.dialog_show_photo); + } + + @Override + public void show() { + super.show(); + WindowManager.LayoutParams layoutParams = getWindow().getAttributes(); + layoutParams.gravity= Gravity.CENTER; + layoutParams.width= WindowManager.LayoutParams.MATCH_PARENT; + layoutParams.height= WindowManager.LayoutParams.MATCH_PARENT; + getWindow().getDecorView().setPadding(0, 0, 0, 0); + getWindow().setAttributes(layoutParams); + } + + public void show(String photoUrl) { + show(); + PhotoView photoView = findViewById(R.id.pv_img); + photoView.setScaleType(ImageView.ScaleType.FIT_XY); + photoView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dismiss(); + } + }); + Glide.with(getContext()).load(photoUrl). + apply(new RequestOptions() + .error(R.drawable.ic_load_imag_eerror)) + .into(photoView); + } + + public void show(Drawable photoDrawable) { + show(); + PhotoView photoView = findViewById(R.id.pv_img); + photoView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dismiss(); + } + }); + if (photoDrawable == null){ + photoView.setImageDrawable(ContextCompat.getDrawable(getContext(),R.drawable.ic_load_imag_eerror)); + }else { + photoView.setImageDrawable(photoDrawable); + } +// Glide.with(getContext()).load(photoDrawable). +// apply(new RequestOptions() +// .error(R.drawable.ic_load_imag_eerror) +// .diskCacheStrategy(DiskCacheStrategy.DATA) +// .skipMemoryCache(true)).into(photoView); + + } + +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/ShowPhotoView.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/ShowPhotoView.java new file mode 100644 index 0000000..2b54164 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/ShowPhotoView.java @@ -0,0 +1,89 @@ +package com.ycgis.macall.personalcenter.v.photoview; + +import android.app.Dialog; +import android.content.Context; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; + +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.rs.macall.androidx.basemodel.callback.SimpleListClickListener; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.v.custom.HorizonSlideRecycleView; + +import java.io.File; +import java.util.List; + +public class ShowPhotoView { + private Context context; + private List fileArray; + private Dialog dialog; + private LinearLayoutManager manager; + private PhotoViewAdapter adapter; + + public ShowPhotoView(Context context){ + this.context = context; + } + + public void setPhotoList(List fileArray){ + this.fileArray = fileArray; + } + + public void showPhoto(int pointer){ + if (fileArray == null || fileArray.isEmpty()){ + ToastUtil.centered(context,"照片不存在!"); + return; + } + File file = new File(fileArray.get(pointer)); + if (!file.exists()){ + ToastUtil.centered(context,"照片不存在!"); + return; + } + if (dialog == null){ + View view = LayoutInflater.from(context).inflate(R.layout.dialog_photo_view,null); + HorizonSlideRecycleView rv_photo = view.findViewById(R.id.rv_photo); + manager = new LinearLayoutManager(context); + manager.setOrientation(LinearLayoutManager.HORIZONTAL); + rv_photo.setLayoutManager(manager); + adapter = new PhotoViewAdapter(context,fileArray); + rv_photo.setAdapter(adapter); + + dialog = new Dialog(context); + dialog.setContentView(view); + dialog.setCancelable(true); + Window window = dialog.getWindow(); + assert window != null; + //设置在屏幕下边 + window.setGravity(Gravity.CENTER); + WindowManager.LayoutParams params = window.getAttributes(); + params.width = WindowManager.LayoutParams.MATCH_PARENT; + params.height = WindowManager.LayoutParams.MATCH_PARENT; + //消除边距 + window.setBackgroundDrawable(null); + window.setAttributes(params); + } + if (adapter!= null){ + adapter.upData(fileArray); + if (pointer >0){ + manager.scrollToPositionWithOffset(pointer, 0); + manager.setStackFromEnd(true); + } + } + dialog.show(); + adapter.setListClickListener(new SimpleListClickListener() { + @Override + public void onSingleClick(View v, int pointer) { + dialog.dismiss(); + } + + @Override + public void onFastClick(View v, int pointer) { + + } + }); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/Util.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/Util.java new file mode 100644 index 0000000..c333e24 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/photoview/Util.java @@ -0,0 +1,37 @@ +package com.ycgis.macall.personalcenter.v.photoview; + +import android.view.MotionEvent; +import android.widget.ImageView; + +class Util { + + static void checkZoomLevels(float minZoom, float midZoom, + float maxZoom) { + if (minZoom >= midZoom) { + throw new IllegalArgumentException( + "Minimum zoom has to be less than Medium zoom. Call setMinimumZoom() with a more appropriate value"); + } else if (midZoom >= maxZoom) { + throw new IllegalArgumentException( + "Medium zoom has to be less than Maximum zoom. Call setMaximumZoom() with a more appropriate value"); + } + } + + static boolean hasDrawable(ImageView imageView) { + return imageView.getDrawable() != null; + } + + static boolean isSupportedScaleType(final ImageView.ScaleType scaleType) { + if (scaleType == null) { + return false; + } + switch (scaleType) { + case MATRIX: + throw new IllegalStateException("Matrix scale type is not supported"); + } + return true; + } + + static int getPointerIndex(int action) { + return (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/viewmodel/HomeViewModel.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/viewmodel/HomeViewModel.java new file mode 100644 index 0000000..0bba8a9 --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/viewmodel/HomeViewModel.java @@ -0,0 +1,364 @@ +package com.ycgis.macall.personalcenter.v.viewmodel; + +import android.graphics.Bitmap; +import android.text.Html; +import android.util.Log; +import android.widget.ImageView; + +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.MediatorLiveData; +import androidx.lifecycle.Observer; + +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewModel; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.ycgis.macall.personalcenter.R; +import com.ycgis.macall.personalcenter.m.adapterbean.AppBean; +import com.ycgis.macall.personalcenter.m.adapterbean.AppInfoBean; +import com.ycgis.macall.personalcenter.m.adapterbean.HomeMessageBean; +import com.ycgis.macall.personalcenter.m.adapterbean.MessageBean; +import com.ycgis.macall.personalcenter.m.requestbean.BaseRequestModel; +import com.ycgis.macall.personalcenter.m.requestbean.HomeBannerBean; +import com.ycgis.macall.personalcenter.m.requestbean.PagingModel; +import com.ycgis.macall.personalcenter.p.app.AppCache; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.callback.ImageCallBack; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.LoadPhotoImage; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * created by: Macall + * create time: 2023/11/9 14:14 + * copyright: @ruansee.com + * Describe: + */ +public class HomeViewModel extends BaseViewModel { + + private final MediatorLiveData> bannerList = new MediatorLiveData<>(); + private final MediatorLiveData> appList = new MediatorLiveData<>(); + private final MediatorLiveData msgList = new MediatorLiveData<>(); + + public void addBannerData(LifecycleOwner owner, Observer> observer) { + addLiveDataObserve(owner, bannerList, observer); + } + + public void addAppList(LifecycleOwner owner, Observer> observer) { + addLiveDataObserve(owner, appList, observer); + } + + public void addMsgList(LifecycleOwner owner, Observer observer) { + addLiveDataObserve(owner, msgList, observer); + } + + public void getBanner() { + ApiModel.request(RetrofitService.getBaseInstance().getBannerList(), new BaseRequestCallback>>() { + @Override + public void onRequestFailure(String msg) { + bannerList.postValue(getErrorBanner()); + } + + @Override + public void onRequestSuccess(BaseRequestModel> result) { + List imageViewList = new ArrayList<>(); + if (result.getCode() == 20041) { + List data = result.getData(); + if (data != null && !data.isEmpty()) { + Collections.sort(data); + for (HomeBannerBean b : data) { + imageViewList.add(AppCache.BASE_IMAGE_URL + b.getUrl()); + } + } else { + imageViewList.addAll(getErrorBanner()); + } + } else { + imageViewList.addAll(getErrorBanner()); + } + bannerList.postValue(imageViewList); + } + }); + } + + private List getErrorBanner() { + List imageViewList = new ArrayList<>(); + imageViewList.add(R.drawable.icon_banner1); + imageViewList.add(R.drawable.icon_banner2); + imageViewList.add(R.drawable.icon_banner3); + imageViewList.add(R.drawable.icon_banner4); + imageViewList.add(R.drawable.icon_banner5); + return imageViewList; + } + + public void getAppList() { + ApiModel.request(RetrofitService.getBaseInstance().recommendApplication(), new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + Log.e(TAG, msg); + hintTuiJianApp(-1, msg); + } + + @Override + public void onRequestSuccess(JsonObject result) { + Log.w(TAG, result.toString()); + try { + JSONObject object = new JSONObject(result.toString()); + String code = TypConversion.getJsonStr(object, "code"); + if (code.equals("20041")) { + List modelList1 = new ArrayList<>(); + JSONObject data = TypConversion.getJSONObject(object, "data"); + if (data == null) { + hintTuiJianApp(0, "暂无应用"); + return; + } + JSONArray tjyy = TypConversion.getJSONArray(data, "推荐应用"); + JSONArray zxyy = TypConversion.getJSONArray(data, "最新应用"); + + if (zxyy != null) { + modelList1.addAll(hanAppData(zxyy)); + } + if (tjyy != null) { + modelList1.addAll(hanAppData(tjyy)); + } + if (modelList1.isEmpty()) { + hintTuiJianApp(0, "暂无应用"); + } else { + AppBean bean = null; + if (modelList1.size() >= 8) { + modelList1 = modelList1.subList(0, 8); + bean = modelList1.remove(7); + } else { + bean = new AppBean(); + } + bean.setBaseType(1); + bean.setAppName("更多应用"); + bean.setIcon(R.drawable.icon_gd2); + bean.setIconUrl(""); + modelList1.add(bean); + appList.postValue(modelList1); + } + } else { + hintTuiJianApp(-1, TypConversion.getJsonStr(object, "msg")); + } + } catch (JSONException e) { + e.printStackTrace(); + hintTuiJianApp(-1, e.getMessage()); + } + } + }); + } + + private List hanAppData(JSONArray array) { + List dataList = new ArrayList<>(); + for (int i = 0; i < array.length(); i++) { + JSONObject jsonObject = TypConversion.getJSONObject(array, i); + if (jsonObject == null) continue; + AppBean bean = new AppBean(); + bean.setBaseType(1); + bean.setAppName(TypConversion.getJsonStr(jsonObject, "name")); + bean.setId(TypConversion.getJsonStr(jsonObject, "id")); + bean.setAppType(TypConversion.getJsonStr(jsonObject, "level")); + if ("3".equals(bean.getAppType())) { + bean.setLinkUrl(TypConversion.getJsonStr(jsonObject, "packageName")); + } else { + bean.setLinkUrl(TypConversion.getJsonStr(jsonObject, "link")); + } + String type = TypConversion.getJsonStr(jsonObject, "type"); + if (type.equals("1")) { + bean.setNetworkType("Ⅱ类应用"); + } else if (type.equals("2")) { + bean.setNetworkType("Ⅲ类应用"); + } + bean.setClientId(TypConversion.getJsonStr(jsonObject, "clientId")); + bean.setClientSecret(TypConversion.getJsonStr(jsonObject, "clientSecret")); + bean.setIconUrl(TypConversion.getJsonStr(jsonObject, "icon")); + bean.setClassification(TypConversion.getJsonStr(jsonObject, "classification")); + bean.setCompany(TypConversion.getJsonStr(jsonObject, "serviceProvider")); + bean.setOperationName(TypConversion.getJsonStr(jsonObject, "operationPerson")); + bean.setOperationPhone(TypConversion.getJsonStr(jsonObject, "phoneNumber")); + bean.setTime(TypConversion.getJsonStr(jsonObject, "applicationTime")); + dataList.add(bean); + } + return dataList; + } + + private void hintTuiJianApp(int type, String msg) { + List modelList1 = new ArrayList<>(); +// AppBean bean = new AppBean(); +// bean.setBaseType(type); +// bean.setBaseMessage(msg); +// modelList1.add(bean); + + if (type == 0) { + AppBean bean = new AppBean(); + bean.setBaseType(1); + bean.setAppName("应用指南"); + bean.setIcon(R.drawable.ic_zfjc); + modelList1.add(bean); + AppBean bean1 = new AppBean(); + bean1.setBaseType(1); + bean1.setAppName("常见问题"); + bean1.setIcon(R.drawable.ic_zazh); + modelList1.add(bean1); + AppBean bean2 = new AppBean(); + bean2.setBaseType(1); + bean2.setAppName("意见反馈"); + bean2.setIcon(R.drawable.ic_ybss); + modelList1.add(bean2); + } else { + AppBean bean = new AppBean(); + bean.setBaseType(type); + bean.setBaseMessage(msg); + modelList1.add(bean); + } + appList.postValue(modelList1); + } + + public void getMessage() { + ApiModel.request(RetrofitService.getBaseInstance().getMessage(0, 1, 3), + new BaseRequestCallback>>() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(TAG, msg); + HomeMessageBean homeMessageBean = new HomeMessageBean(); + List messageBeanList = new ArrayList<>(); + MessageBean bean = new MessageBean(); + bean.setBaseType(-1); + bean.setBaseMessage(msg); + homeMessageBean.setTitle("全部消息"); + homeMessageBean.setCount(0); + homeMessageBean.setMessageBeanList(messageBeanList); + messageBeanList.add(bean); + msgList.postValue(homeMessageBean); + } + + @Override + public void onRequestSuccess(BaseRequestModel> result) { +// LogUtils.w(TAG, result.toString()); + HomeMessageBean homeMessageBean = new HomeMessageBean(); + List messageBeanList = new ArrayList<>(); + if (result.getCode() == 20041) { + PagingModel data = result.getData(); + if (data == null) { + homeMessageBean.setTitle("全部消息"); + MessageBean bean = new MessageBean(); + bean.setBaseType(0); + bean.setBaseMessage("暂无新消息"); + messageBeanList.add(bean); + homeMessageBean.setMessageBeanList(messageBeanList); + msgList.postValue(homeMessageBean); + return; + } + int counts = data.getCounts(); + List items = data.getItems(); + if (items.isEmpty()) { + homeMessageBean.setTitle("全部消息"); + MessageBean bean = new MessageBean(); + bean.setBaseType(0); + bean.setBaseMessage("暂无新消息"); + messageBeanList.add(bean); + homeMessageBean.setMessageBeanList(messageBeanList); + msgList.postValue(homeMessageBean); + return; + } + String title = "全部消息(" + counts + ""; + homeMessageBean.setTitle(title); + homeMessageBean.setCount(counts); + for (MessageBean bean : items) { + bean.setBaseType(1); + } + homeMessageBean.setMessageBeanList(items); + msgList.postValue(homeMessageBean); + } else { + MessageBean bean = new MessageBean(); + bean.setBaseType(0); + bean.setBaseMessage(result.getMsg()); + messageBeanList.add(bean); + homeMessageBean.setTitle("全部消息"); + homeMessageBean.setMessageBeanList(messageBeanList); + msgList.postValue(homeMessageBean); + } +// +// List messageBeanList = new ArrayList<>(); +// try { +// JSONObject object = new JSONObject(result.toString()); +// String code = TypConversion.getJsonStr(object, "code"); +// if (code.equals("20041")) { +// JSONObject data = object.getJSONObject("data"); +// int counts = TypConversion.getJsonInt(data, "counts", 0); +// homeMessageBean.setCount(counts); +// if (counts <= 0) { +// homeMessageBean.setTitle("全部消息"); +// MessageBean bean = new MessageBean(); +// bean.setBaseType(0); +// bean.setBaseMessage("暂无新消息"); +// messageBeanList.add(bean); +// homeMessageBean.setMessageBeanList(messageBeanList); +// msgList.postValue(homeMessageBean); +// return; +// } +// String title = "全部消息(" + counts + ""; +// homeMessageBean.setTitle(title); +// JSONArray items = data.getJSONArray("items"); +// int lengthNum = Math.min(items.length(), 3); +// for (int i = 0; i < lengthNum; i++) { +// JSONObject jsonObject = TypConversion.getJSONObject(items, i); +// if (jsonObject == null) continue; +// MessageBean bean = new MessageBean(); +// bean.setBaseType(1); +// bean.setAppName(TypConversion.getJsonStr(jsonObject, "appName")); +// bean.setId(TypConversion.getJsonStr(jsonObject, "id")); +// bean.setMsgId(TypConversion.getJsonStr(jsonObject, "msgId")); +// bean.setTitle(TypConversion.getJsonStr(jsonObject, "msgTitle")); +// bean.setContent(TypConversion.getJsonStr(jsonObject, "msgContent")); +// bean.setClientId(TypConversion.getJsonStr(jsonObject, "appId")); +// bean.setClientSecret(TypConversion.getJsonStr(jsonObject, "appSecret")); +// bean.setAppLinkUrl(TypConversion.getJsonStr(jsonObject, "appUrl")); +// bean.setMsgType(TypConversion.getJsonStr(jsonObject, "msgType")); +// bean.setTime(TypConversion.getJsonStr(jsonObject, "sendingTime")); +// int state = TypConversion.getJsonInt(jsonObject, "state", 0); +// bean.setRead(state != 0); +// messageBeanList.add(bean); +// } +// if (messageBeanList.isEmpty()) { +// MessageBean bean = new MessageBean(); +// bean.setBaseType(0); +// bean.setBaseMessage("暂无新消息"); +// homeMessageBean.setTitle("全部消息"); +// messageBeanList.add(bean); +// } +// homeMessageBean.setMessageBeanList(messageBeanList); +// msgList.postValue(homeMessageBean); +// return; +// } +// MessageBean bean = new MessageBean(); +// bean.setBaseType(0); +// bean.setBaseMessage(TypConversion.getJsonStr(object, "msg")); +// messageBeanList.add(bean); +// homeMessageBean.setTitle("全部消息"); +// homeMessageBean.setMessageBeanList(messageBeanList); +// msgList.postValue(homeMessageBean); +// } catch (JSONException e) { +// e.printStackTrace(); +// MessageBean bean = new MessageBean(); +// bean.setBaseType(-1); +// bean.setBaseMessage(e.getMessage()); +// messageBeanList.add(bean); +// homeMessageBean.setTitle("全部消息"); +// homeMessageBean.setMessageBeanList(messageBeanList); +// msgList.postValue(homeMessageBean); +// } + } + }); + } +} diff --git a/app/src/main/java/com/ycgis/macall/personalcenter/v/viewmodel/MyDetailsViewModel.java b/app/src/main/java/com/ycgis/macall/personalcenter/v/viewmodel/MyDetailsViewModel.java new file mode 100644 index 0000000..bccff0b --- /dev/null +++ b/app/src/main/java/com/ycgis/macall/personalcenter/v/viewmodel/MyDetailsViewModel.java @@ -0,0 +1,159 @@ +package com.ycgis.macall.personalcenter.v.viewmodel; + +import android.os.Message; +import android.util.Log; + +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.MediatorLiveData; +import androidx.lifecycle.Observer; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.rs.macall.androidx.basemodel.base.BaseViewModel; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.TypConversion; +import com.ycgis.macall.personalcenter.m.adapterbean.BaseBean; +import com.ycgis.macall.personalcenter.p.app.AppCache; +import com.ycgis.macall.personalcenter.p.app.RuanseeApplication; +import com.ycgis.macall.personalcenter.p.app.UserData; +import com.ycgis.macall.personalcenter.p.callback.BaseRequestCallback; +import com.ycgis.macall.personalcenter.p.request.ApiModel; +import com.ycgis.macall.personalcenter.p.request.RetrofitService; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * created by: Macall + * create time: 2023/11/22 11:46 + * copyright: @ruansee.com + * Describe: + */ +public class MyDetailsViewModel extends BaseViewModel { + private MediatorLiveData updateLiveData = new MediatorLiveData<>(); + + public void addUpdateLiveDataObserve(LifecycleOwner owner, Observer observer) { + addLiveDataObserve(owner, updateLiveData, observer); + } + + public void sendUpdate(int mun, final String value, String imsi, String imei) { + final Map param = new HashMap<>(); + AppCache cacheData = RuanseeApplication.getAppCache(); + param.put("token", cacheData.getToken()); + param.put("clientType", "MOBILE"); + param.put("imsi1", imsi); + param.put("deviceFlags", imei); + param.put("sysCode", cacheData.getSysmCode()); + if (mun == 1) { + param.put("workPhone", value); + } else if (mun == 2) { + param.put("phoneNum", value); + } + ApiModel.request("updateUser", + RetrofitService.getBaseInstance().getLoginType("http://20.90.2.2/UniAuth/api/sso/v1/updateUserInfo", param), + new BaseRequestCallback() { + @Override + public void onRequestFailure(String msg) { + LogUtils.e(TAG, msg); + BaseBean b = new BaseBean() { + }; + b.setBaseType(-1); + b.setBaseMessage(msg); + updateLiveData.postValue(b); + } + + @Override + public void onRequestSuccess(JsonObject result) { + LogUtils.w(TAG, result.toString()); + ApiModel.uploadOperationLog("3","3","用户修改统一用户手机号码"); + try { + JSONObject object = new JSONObject(result.toString()); + int code = TypConversion.getJsonInt(object, "code", -1); + if (code == 200) { + List payloads = getPayloads(); + BaseBean b = new BaseBean() { + }; + if (payloads!=null&&!payloads.isEmpty()){ + b.setBaseType((Integer) payloads.get(0)); + b.setBaseMessage((String) payloads.get(1)); + } + updateLiveData.postValue(b); + }else { + BaseBean b = new BaseBean() { + }; + b.setBaseType(-1); + b.setBaseMessage(StringUtil.get(TypConversion.getJsonStr(object,"msg"),TypConversion.getJsonStr(object,"content"))); + updateLiveData.postValue(b); + } + } catch (JSONException e) { + e.printStackTrace(); + BaseBean b = new BaseBean() { + }; + b.setBaseType(-1); + b.setBaseMessage(e.getMessage()); + updateLiveData.postValue(b); + } + } + } + .addPayload(mun) + .addPayload(value)); +// BaseRequest.postRequest("phone/updateUser", json, new SyncCallBack() { +// @Override +// public void onSucceed(int responseCode, String message) { +// Log.w(TAG, message); +// try { +// JSONObject object = new JSONObject(message); +// String code = TypConversion.getJsonStr(object, "code"); +// if (StringUtil.hasContent(code) && code.equals("0")) { +// if (position == 7) { +// MyApplication.getAppCacheData().setPhone1(value); +// } else if (position == 8) { +// MyApplication.getAppCacheData().setPhone2(value); +// } else if (position == 9) { +// +// } +// myHandler.sendEmptyMessage(200); +// return; +// } +// if (StringUtil.isNullOrEmpty(code) || code.equals("-1")) { +// // 必传参数为空 +// Message message1 = myHandler.obtainMessage(-140, "缺少必传参数!"); +// myHandler.sendMessage(message1); +// return; +// } +// if (code.equals("-2")) { +// // 修改失败 +// Message message1 = myHandler.obtainMessage(-140, "修改失败,请联系管理员!"); +// myHandler.sendMessage(message1); +// return; +// } +// if (code.equals("500")) { +// // 修改失败 +// Message message1 = myHandler.obtainMessage(-500, "服务错误,请联系管理员!"); +// myHandler.sendMessage(message1); +// return; +// } +// isUpdata = false; +// } catch (JSONException e) { +// e.printStackTrace(); +// Message message1 = myHandler.obtainMessage(-140, "解析失败,请联系管理员!"); +// myHandler.sendMessage(message1); +// } +// } +// +// @Override +// public void onFail(int responseCode, String message) { +// Log.e(TAG, message); +// Message message1 = myHandler.obtainMessage(responseCode, message); +// myHandler.sendMessage(message1); +// } +// }); + } + + +} diff --git a/app/src/main/res/anim/anim_in.xml b/app/src/main/res/anim/anim_in.xml new file mode 100644 index 0000000..508da94 --- /dev/null +++ b/app/src/main/res/anim/anim_in.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/anim_out.xml b/app/src/main/res/anim/anim_out.xml new file mode 100644 index 0000000..ee69da7 --- /dev/null +++ b/app/src/main/res/anim/anim_out.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/dialog_scale_in.xml b/app/src/main/res/anim/dialog_scale_in.xml new file mode 100644 index 0000000..5063240 --- /dev/null +++ b/app/src/main/res/anim/dialog_scale_in.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/dialog_scale_out.xml b/app/src/main/res/anim/dialog_scale_out.xml new file mode 100644 index 0000000..8e02e91 --- /dev/null +++ b/app/src/main/res/anim/dialog_scale_out.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/image_rotate_once.xml b/app/src/main/res/anim/image_rotate_once.xml new file mode 100644 index 0000000..733a5e4 --- /dev/null +++ b/app/src/main/res/anim/image_rotate_once.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-xxhdpi/ic_transit.png b/app/src/main/res/drawable-xxhdpi/ic_transit.png new file mode 100644 index 0000000..fb23487 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_transit.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_usercenter.png b/app/src/main/res/drawable-xxhdpi/ic_usercenter.png new file mode 100644 index 0000000..1b57a7f Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_usercenter.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_ybss.png b/app/src/main/res/drawable-xxhdpi/ic_ybss.png new file mode 100644 index 0000000..9de5fec Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_ybss.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_ycyj.png b/app/src/main/res/drawable-xxhdpi/ic_ycyj.png new file mode 100644 index 0000000..5e93167 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_ycyj.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_yqyj.png b/app/src/main/res/drawable-xxhdpi/ic_yqyj.png new file mode 100644 index 0000000..048c7a1 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_yqyj.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_zaff.png b/app/src/main/res/drawable-xxhdpi/ic_zaff.png new file mode 100644 index 0000000..a52773a Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_zaff.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_zazdr.png b/app/src/main/res/drawable-xxhdpi/ic_zazdr.png new file mode 100644 index 0000000..6657378 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_zazdr.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_zazh.png b/app/src/main/res/drawable-xxhdpi/ic_zazh.png new file mode 100644 index 0000000..e0e4d37 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_zazh.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_zfjc.png b/app/src/main/res/drawable-xxhdpi/ic_zfjc.png new file mode 100644 index 0000000..c5b5ae5 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_zfjc.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_zhyy.png b/app/src/main/res/drawable-xxhdpi/ic_zhyy.png new file mode 100644 index 0000000..8259fd7 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_zhyy.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_main_feedback.png b/app/src/main/res/drawable-xxhdpi/icon_main_feedback.png new file mode 100644 index 0000000..383788d Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_main_feedback.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_main_feedback_def.png b/app/src/main/res/drawable-xxhdpi/icon_main_feedback_def.png new file mode 100644 index 0000000..69a4e13 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_main_feedback_def.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_main_home.png b/app/src/main/res/drawable-xxhdpi/icon_main_home.png new file mode 100644 index 0000000..7723183 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_main_home.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_main_home_def.png b/app/src/main/res/drawable-xxhdpi/icon_main_home_def.png new file mode 100644 index 0000000..08a9e6c Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_main_home_def.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_main_message.png b/app/src/main/res/drawable-xxhdpi/icon_main_message.png new file mode 100644 index 0000000..5eb7b3e Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_main_message.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_main_message_def.png b/app/src/main/res/drawable-xxhdpi/icon_main_message_def.png new file mode 100644 index 0000000..f67ab99 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_main_message_def.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_main_my.png b/app/src/main/res/drawable-xxhdpi/icon_main_my.png new file mode 100644 index 0000000..3103ec5 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_main_my.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_main_my_def.png b/app/src/main/res/drawable-xxhdpi/icon_main_my_def.png new file mode 100644 index 0000000..52ac687 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_main_my_def.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_main_work.png b/app/src/main/res/drawable-xxhdpi/icon_main_work.png new file mode 100644 index 0000000..794c60a Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_main_work.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_main_work_def.png b/app/src/main/res/drawable-xxhdpi/icon_main_work_def.png new file mode 100644 index 0000000..1b34c9b Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_main_work_def.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_search.png b/app/src/main/res/drawable-xxhdpi/icon_search.png new file mode 100644 index 0000000..8ea0a9e Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_search.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/arrow_right.png b/app/src/main/res/drawable-xxxhdpi/arrow_right.png new file mode 100644 index 0000000..6d1657e Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/arrow_right.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/banner.png b/app/src/main/res/drawable-xxxhdpi/banner.png new file mode 100644 index 0000000..1c04773 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/banner.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/banner2.png b/app/src/main/res/drawable-xxxhdpi/banner2.png new file mode 100644 index 0000000..ad0a857 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/banner2.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/bg_two.png b/app/src/main/res/drawable-xxxhdpi/bg_two.png new file mode 100644 index 0000000..b762dc2 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/bg_two.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/fileselect_img_doc.png b/app/src/main/res/drawable-xxxhdpi/fileselect_img_doc.png new file mode 100644 index 0000000..4e6da43 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/fileselect_img_doc.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/fileselect_img_music.png b/app/src/main/res/drawable-xxxhdpi/fileselect_img_music.png new file mode 100644 index 0000000..1266cce Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/fileselect_img_music.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/fileselect_img_pfd.png b/app/src/main/res/drawable-xxxhdpi/fileselect_img_pfd.png new file mode 100644 index 0000000..e9293cf Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/fileselect_img_pfd.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/fileselect_img_ppt.PNG b/app/src/main/res/drawable-xxxhdpi/fileselect_img_ppt.PNG new file mode 100644 index 0000000..93365fc Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/fileselect_img_ppt.PNG differ diff --git a/app/src/main/res/drawable-xxxhdpi/fileselect_img_txt.png b/app/src/main/res/drawable-xxxhdpi/fileselect_img_txt.png new file mode 100644 index 0000000..357ea7c Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/fileselect_img_txt.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/fileselect_img_unknown.png b/app/src/main/res/drawable-xxxhdpi/fileselect_img_unknown.png new file mode 100644 index 0000000..d4ef3ff Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/fileselect_img_unknown.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/fileselect_img_xls.png b/app/src/main/res/drawable-xxxhdpi/fileselect_img_xls.png new file mode 100644 index 0000000..8d99e7f Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/fileselect_img_xls.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/fileselect_img_zip.png b/app/src/main/res/drawable-xxxhdpi/fileselect_img_zip.png new file mode 100644 index 0000000..7b599f4 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/fileselect_img_zip.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_allread.png b/app/src/main/res/drawable-xxxhdpi/ic_allread.png new file mode 100644 index 0000000..ba89005 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_allread.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_apply_for_bg.jpg b/app/src/main/res/drawable-xxxhdpi/ic_apply_for_bg.jpg new file mode 100644 index 0000000..fdee092 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_apply_for_bg.jpg differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_arrow_bottom.png b/app/src/main/res/drawable-xxxhdpi/ic_arrow_bottom.png new file mode 100644 index 0000000..cdeec26 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_arrow_bottom.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_arrow_right.png b/app/src/main/res/drawable-xxxhdpi/ic_arrow_right.png new file mode 100644 index 0000000..ac2a7ad Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_arrow_right.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_back.png b/app/src/main/res/drawable-xxxhdpi/ic_back.png new file mode 100644 index 0000000..bd550d5 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_back.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_back_b.png b/app/src/main/res/drawable-xxxhdpi/ic_back_b.png new file mode 100644 index 0000000..9c3c2ed Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_back_b.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_details.png b/app/src/main/res/drawable-xxxhdpi/ic_details.png new file mode 100644 index 0000000..c1ed158 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_details.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_dropup.png b/app/src/main/res/drawable-xxxhdpi/ic_dropup.png new file mode 100644 index 0000000..d1c7f46 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_dropup.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_filter.png b/app/src/main/res/drawable-xxxhdpi/ic_filter.png new file mode 100644 index 0000000..f55c299 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_filter.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_load_imag_eerror.png b/app/src/main/res/drawable-xxxhdpi/ic_load_imag_eerror.png new file mode 100644 index 0000000..447a7ce Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_load_imag_eerror.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_look.png b/app/src/main/res/drawable-xxxhdpi/ic_look.png new file mode 100644 index 0000000..e438ec2 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_look.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_network_normal.png b/app/src/main/res/drawable-xxxhdpi/ic_network_normal.png new file mode 100644 index 0000000..ff76f0a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_network_normal.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_network_pause.png b/app/src/main/res/drawable-xxxhdpi/ic_network_pause.png new file mode 100644 index 0000000..ec14658 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_network_pause.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_not_select.png b/app/src/main/res/drawable-xxxhdpi/ic_not_select.png new file mode 100644 index 0000000..4f7fc20 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_not_select.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_police_log.png b/app/src/main/res/drawable-xxxhdpi/ic_police_log.png new file mode 100644 index 0000000..8fee314 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_police_log.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_select.png b/app/src/main/res/drawable-xxxhdpi/ic_select.png new file mode 100644 index 0000000..7901b51 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_select.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_transit.png b/app/src/main/res/drawable-xxxhdpi/ic_transit.png new file mode 100644 index 0000000..fb23487 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_transit.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_unread1.png b/app/src/main/res/drawable-xxxhdpi/ic_unread1.png new file mode 100644 index 0000000..ee08307 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_unread1.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_unread_doit.png b/app/src/main/res/drawable-xxxhdpi/ic_unread_doit.png new file mode 100644 index 0000000..bbf47c3 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_unread_doit.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_ybss.png b/app/src/main/res/drawable-xxxhdpi/ic_ybss.png new file mode 100644 index 0000000..c550fd3 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_ybss.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_ycyj.png b/app/src/main/res/drawable-xxxhdpi/ic_ycyj.png new file mode 100644 index 0000000..1029ff1 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_ycyj.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_yqyj.png b/app/src/main/res/drawable-xxxhdpi/ic_yqyj.png new file mode 100644 index 0000000..aa30f84 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_yqyj.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_zaff.png b/app/src/main/res/drawable-xxxhdpi/ic_zaff.png new file mode 100644 index 0000000..fe3a15e Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_zaff.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_zazdr.png b/app/src/main/res/drawable-xxxhdpi/ic_zazdr.png new file mode 100644 index 0000000..89c8bf5 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_zazdr.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_zazh.png b/app/src/main/res/drawable-xxxhdpi/ic_zazh.png new file mode 100644 index 0000000..361366e Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_zazh.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_zfjc.png b/app/src/main/res/drawable-xxxhdpi/ic_zfjc.png new file mode 100644 index 0000000..6f76c1e Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_zfjc.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_zhyy.png b/app/src/main/res/drawable-xxxhdpi/ic_zhyy.png new file mode 100644 index 0000000..03d92fe Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_zhyy.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_about.png b/app/src/main/res/drawable-xxxhdpi/icon_about.png new file mode 100644 index 0000000..f1fb20f Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_about.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_add_def.png b/app/src/main/res/drawable-xxxhdpi/icon_add_def.png new file mode 100644 index 0000000..0518f21 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_add_def.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_apply_for_logo.png b/app/src/main/res/drawable-xxxhdpi/icon_apply_for_logo.png new file mode 100644 index 0000000..bea49f2 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_apply_for_logo.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_authen.png b/app/src/main/res/drawable-xxxhdpi/icon_authen.png new file mode 100644 index 0000000..f5477e3 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_authen.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_banner1.png b/app/src/main/res/drawable-xxxhdpi/icon_banner1.png new file mode 100644 index 0000000..3b3ca2c Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_banner1.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_banner2.png b/app/src/main/res/drawable-xxxhdpi/icon_banner2.png new file mode 100644 index 0000000..3d7de24 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_banner2.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_banner3.png b/app/src/main/res/drawable-xxxhdpi/icon_banner3.png new file mode 100644 index 0000000..937f333 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_banner3.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_banner4.png b/app/src/main/res/drawable-xxxhdpi/icon_banner4.png new file mode 100644 index 0000000..e2f0b0c Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_banner4.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_banner5.png b/app/src/main/res/drawable-xxxhdpi/icon_banner5.png new file mode 100644 index 0000000..d632e5b Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_banner5.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_city.png b/app/src/main/res/drawable-xxxhdpi/icon_city.png new file mode 100644 index 0000000..e07b4dc Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_city.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_clean.png b/app/src/main/res/drawable-xxxhdpi/icon_clean.png new file mode 100644 index 0000000..05a95ee Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_clean.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_edit.png b/app/src/main/res/drawable-xxxhdpi/icon_edit.png new file mode 100644 index 0000000..08bd3ab Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_edit.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_edit_info.png b/app/src/main/res/drawable-xxxhdpi/icon_edit_info.png new file mode 100644 index 0000000..580ec6f Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_edit_info.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_error2.png b/app/src/main/res/drawable-xxxhdpi/icon_error2.png new file mode 100644 index 0000000..6f3c01b Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_error2.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_feedback.png b/app/src/main/res/drawable-xxxhdpi/icon_feedback.png new file mode 100644 index 0000000..a254ea7 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_feedback.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_gd.png b/app/src/main/res/drawable-xxxhdpi/icon_gd.png new file mode 100644 index 0000000..635ab91 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_gd.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_gd2.png b/app/src/main/res/drawable-xxxhdpi/icon_gd2.png new file mode 100644 index 0000000..326f8fa Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_gd2.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_grpm.png b/app/src/main/res/drawable-xxxhdpi/icon_grpm.png new file mode 100644 index 0000000..2b6b68d Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_grpm.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_item_sel.png b/app/src/main/res/drawable-xxxhdpi/icon_item_sel.png new file mode 100644 index 0000000..f0cadd3 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_item_sel.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_jg.png b/app/src/main/res/drawable-xxxhdpi/icon_jg.png new file mode 100644 index 0000000..5ddb783 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_jg.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_main_feedback.png b/app/src/main/res/drawable-xxxhdpi/icon_main_feedback.png new file mode 100644 index 0000000..68b23ce Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_main_feedback.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_main_feedback_def.png b/app/src/main/res/drawable-xxxhdpi/icon_main_feedback_def.png new file mode 100644 index 0000000..220b01a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_main_feedback_def.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_main_home.png b/app/src/main/res/drawable-xxxhdpi/icon_main_home.png new file mode 100644 index 0000000..98816e8 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_main_home.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_main_home_def.png b/app/src/main/res/drawable-xxxhdpi/icon_main_home_def.png new file mode 100644 index 0000000..9ed29ed Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_main_home_def.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_main_message.png b/app/src/main/res/drawable-xxxhdpi/icon_main_message.png new file mode 100644 index 0000000..a0dda53 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_main_message.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_main_message_def.png b/app/src/main/res/drawable-xxxhdpi/icon_main_message_def.png new file mode 100644 index 0000000..b207d7a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_main_message_def.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_main_my.png b/app/src/main/res/drawable-xxxhdpi/icon_main_my.png new file mode 100644 index 0000000..b429efe Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_main_my.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_main_my_def.png b/app/src/main/res/drawable-xxxhdpi/icon_main_my_def.png new file mode 100644 index 0000000..b020d78 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_main_my_def.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_main_title_bg.png b/app/src/main/res/drawable-xxxhdpi/icon_main_title_bg.png new file mode 100644 index 0000000..8c9f9e0 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_main_title_bg.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_main_work.png b/app/src/main/res/drawable-xxxhdpi/icon_main_work.png new file mode 100644 index 0000000..e74268b Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_main_work.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_main_work_def.png b/app/src/main/res/drawable-xxxhdpi/icon_main_work_def.png new file mode 100644 index 0000000..5110194 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_main_work_def.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_my_userbg.png b/app/src/main/res/drawable-xxxhdpi/icon_my_userbg.png new file mode 100644 index 0000000..e37e979 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_my_userbg.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_not_record.png b/app/src/main/res/drawable-xxxhdpi/icon_not_record.png new file mode 100644 index 0000000..243f7cf Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_not_record.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_operation_guide.png b/app/src/main/res/drawable-xxxhdpi/icon_operation_guide.png new file mode 100644 index 0000000..52b177b Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_operation_guide.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_over.png b/app/src/main/res/drawable-xxxhdpi/icon_over.png new file mode 100644 index 0000000..d1f9747 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_over.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_over_back.png b/app/src/main/res/drawable-xxxhdpi/icon_over_back.png new file mode 100644 index 0000000..98649fa Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_over_back.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_photo_album.png b/app/src/main/res/drawable-xxxhdpi/icon_photo_album.png new file mode 100644 index 0000000..95f1c57 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_photo_album.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_photo_album_on.png b/app/src/main/res/drawable-xxxhdpi/icon_photo_album_on.png new file mode 100644 index 0000000..1c020ad Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_photo_album_on.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_play.png b/app/src/main/res/drawable-xxxhdpi/icon_play.png new file mode 100644 index 0000000..f2d5519 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_play.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_police_man.png b/app/src/main/res/drawable-xxxhdpi/icon_police_man.png new file mode 100644 index 0000000..d515e42 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_police_man.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_police_woman.png b/app/src/main/res/drawable-xxxhdpi/icon_police_woman.png new file mode 100644 index 0000000..30c4cff Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_police_woman.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_problen.png b/app/src/main/res/drawable-xxxhdpi/icon_problen.png new file mode 100644 index 0000000..54dc98a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_problen.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_record.png b/app/src/main/res/drawable-xxxhdpi/icon_record.png new file mode 100644 index 0000000..ff8f18a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_record.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_refresh.png b/app/src/main/res/drawable-xxxhdpi/icon_refresh.png new file mode 100644 index 0000000..9e7643f Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_refresh.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_refresh_grad.png b/app/src/main/res/drawable-xxxhdpi/icon_refresh_grad.png new file mode 100644 index 0000000..ec19ea6 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_refresh_grad.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_role_sel.png b/app/src/main/res/drawable-xxxhdpi/icon_role_sel.png new file mode 100644 index 0000000..471ae83 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_role_sel.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_scan_code.png b/app/src/main/res/drawable-xxxhdpi/icon_scan_code.png new file mode 100644 index 0000000..5c2b26e Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_scan_code.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_search.png b/app/src/main/res/drawable-xxxhdpi/icon_search.png new file mode 100644 index 0000000..c9fb117 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_search.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/select_def.xml b/app/src/main/res/drawable-xxxhdpi/select_def.xml new file mode 100644 index 0000000..175ba43 --- /dev/null +++ b/app/src/main/res/drawable-xxxhdpi/select_def.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-xxxhdpi/select_xz.xml b/app/src/main/res/drawable-xxxhdpi/select_xz.xml new file mode 100644 index 0000000..d0df2da --- /dev/null +++ b/app/src/main/res/drawable-xxxhdpi/select_xz.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-xxxhdpi/sr_yysqlc.png b/app/src/main/res/drawable-xxxhdpi/sr_yysqlc.png new file mode 100644 index 0000000..116d5ac Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/sr_yysqlc.png differ diff --git a/app/src/main/res/drawable/back_gount_cat_type_bj1.xml b/app/src/main/res/drawable/back_gount_cat_type_bj1.xml new file mode 100644 index 0000000..19eea35 --- /dev/null +++ b/app/src/main/res/drawable/back_gount_cat_type_bj1.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/back_gount_cat_type_bj1_select.xml b/app/src/main/res/drawable/back_gount_cat_type_bj1_select.xml new file mode 100644 index 0000000..e0b32ec --- /dev/null +++ b/app/src/main/res/drawable/back_gount_cat_type_bj1_select.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/back_opinion1.xml b/app/src/main/res/drawable/back_opinion1.xml new file mode 100644 index 0000000..617a5ce --- /dev/null +++ b/app/src/main/res/drawable/back_opinion1.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/back_opinion2.xml b/app/src/main/res/drawable/back_opinion2.xml new file mode 100644 index 0000000..533c124 --- /dev/null +++ b/app/src/main/res/drawable/back_opinion2.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bk_gray.xml b/app/src/main/res/drawable/bk_gray.xml new file mode 100644 index 0000000..f5cc849 --- /dev/null +++ b/app/src/main/res/drawable/bk_gray.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bk_hs.xml b/app/src/main/res/drawable/bk_hs.xml new file mode 100644 index 0000000..6856a9a --- /dev/null +++ b/app/src/main/res/drawable/bk_hs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bk_icon.xml b/app/src/main/res/drawable/bk_icon.xml new file mode 100644 index 0000000..28736d7 --- /dev/null +++ b/app/src/main/res/drawable/bk_icon.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bk_ls.xml b/app/src/main/res/drawable/bk_ls.xml new file mode 100644 index 0000000..7b536e4 --- /dev/null +++ b/app/src/main/res/drawable/bk_ls.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bk_main_color_round_8.xml b/app/src/main/res/drawable/bk_main_color_round_8.xml new file mode 100644 index 0000000..cadd1fa --- /dev/null +++ b/app/src/main/res/drawable/bk_main_color_round_8.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bk_read.xml b/app/src/main/res/drawable/bk_read.xml new file mode 100644 index 0000000..adb858f --- /dev/null +++ b/app/src/main/res/drawable/bk_read.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/btn_bg_right_round.xml b/app/src/main/res/drawable/btn_bg_right_round.xml new file mode 100644 index 0000000..a3940dc --- /dev/null +++ b/app/src/main/res/drawable/btn_bg_right_round.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/btn_photo_album.xml b/app/src/main/res/drawable/btn_photo_album.xml new file mode 100644 index 0000000..e8b8b97 --- /dev/null +++ b/app/src/main/res/drawable/btn_photo_album.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/btn_selecr_back1.xml b/app/src/main/res/drawable/btn_selecr_back1.xml new file mode 100644 index 0000000..1781e24 --- /dev/null +++ b/app/src/main/res/drawable/btn_selecr_back1.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/card_border_white_8.xml b/app/src/main/res/drawable/card_border_white_8.xml new file mode 100644 index 0000000..a4cd332 --- /dev/null +++ b/app/src/main/res/drawable/card_border_white_8.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/card_gray1_round_8.xml b/app/src/main/res/drawable/card_gray1_round_8.xml new file mode 100644 index 0000000..d21cfb5 --- /dev/null +++ b/app/src/main/res/drawable/card_gray1_round_8.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/card_gray_round_8.xml b/app/src/main/res/drawable/card_gray_round_8.xml new file mode 100644 index 0000000..9043891 --- /dev/null +++ b/app/src/main/res/drawable/card_gray_round_8.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/card_white_8.xml b/app/src/main/res/drawable/card_white_8.xml new file mode 100644 index 0000000..ae42fa7 --- /dev/null +++ b/app/src/main/res/drawable/card_white_8.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/card_white_round_4_bk.xml b/app/src/main/res/drawable/card_white_round_4_bk.xml new file mode 100644 index 0000000..d724694 --- /dev/null +++ b/app/src/main/res/drawable/card_white_round_4_bk.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/card_white_round_8.xml b/app/src/main/res/drawable/card_white_round_8.xml new file mode 100644 index 0000000..cdfa75c --- /dev/null +++ b/app/src/main/res/drawable/card_white_round_8.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/edit_brack_select.xml b/app/src/main/res/drawable/edit_brack_select.xml new file mode 100644 index 0000000..6bc3afc --- /dev/null +++ b/app/src/main/res/drawable/edit_brack_select.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/edit_brackgrount.xml b/app/src/main/res/drawable/edit_brackgrount.xml new file mode 100644 index 0000000..fb178fb --- /dev/null +++ b/app/src/main/res/drawable/edit_brackgrount.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/gradient_main.xml b/app/src/main/res/drawable/gradient_main.xml new file mode 100644 index 0000000..4c300e7 --- /dev/null +++ b/app/src/main/res/drawable/gradient_main.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/icon_my_photo_bg.xml b/app/src/main/res/drawable/icon_my_photo_bg.xml new file mode 100644 index 0000000..bcab731 --- /dev/null +++ b/app/src/main/res/drawable/icon_my_photo_bg.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/label_fill_bull.xml b/app/src/main/res/drawable/label_fill_bull.xml new file mode 100644 index 0000000..676e7e1 --- /dev/null +++ b/app/src/main/res/drawable/label_fill_bull.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/mancolor_round_button.xml b/app/src/main/res/drawable/mancolor_round_button.xml new file mode 100644 index 0000000..486dd7e --- /dev/null +++ b/app/src/main/res/drawable/mancolor_round_button.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/my_dept_bg.xml b/app/src/main/res/drawable/my_dept_bg.xml new file mode 100644 index 0000000..257393b --- /dev/null +++ b/app/src/main/res/drawable/my_dept_bg.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_baby_blue.xml b/app/src/main/res/drawable/round_baby_blue.xml new file mode 100644 index 0000000..761a7a5 --- /dev/null +++ b/app/src/main/res/drawable/round_baby_blue.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_bottom_bk_white_8.xml b/app/src/main/res/drawable/round_bottom_bk_white_8.xml new file mode 100644 index 0000000..1e782c7 --- /dev/null +++ b/app/src/main/res/drawable/round_bottom_bk_white_8.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_bottom_white_8.xml b/app/src/main/res/drawable/round_bottom_white_8.xml new file mode 100644 index 0000000..a7d3362 --- /dev/null +++ b/app/src/main/res/drawable/round_bottom_white_8.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_bull.xml b/app/src/main/res/drawable/round_bull.xml new file mode 100644 index 0000000..f9e20ff --- /dev/null +++ b/app/src/main/res/drawable/round_bull.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_gray_all.xml b/app/src/main/res/drawable/round_gray_all.xml new file mode 100644 index 0000000..4ff284a --- /dev/null +++ b/app/src/main/res/drawable/round_gray_all.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_top_bull_6.xml b/app/src/main/res/drawable/round_top_bull_6.xml new file mode 100644 index 0000000..839e491 --- /dev/null +++ b/app/src/main/res/drawable/round_top_bull_6.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_top_white_8.xml b/app/src/main/res/drawable/round_top_white_8.xml new file mode 100644 index 0000000..1faf5a5 --- /dev/null +++ b/app/src/main/res/drawable/round_top_white_8.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_white_all.xml b/app/src/main/res/drawable/round_white_all.xml new file mode 100644 index 0000000..586e185 --- /dev/null +++ b/app/src/main/res/drawable/round_white_all.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/search_bg.xml b/app/src/main/res/drawable/search_bg.xml new file mode 100644 index 0000000..79d6cee --- /dev/null +++ b/app/src/main/res/drawable/search_bg.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/selector_icon_choose_txt_bg.xml b/app/src/main/res/drawable/selector_icon_choose_txt_bg.xml new file mode 100644 index 0000000..3969bed --- /dev/null +++ b/app/src/main/res/drawable/selector_icon_choose_txt_bg.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_icon_choose_no_select.xml b/app/src/main/res/drawable/shape_icon_choose_no_select.xml new file mode 100644 index 0000000..2462dcd --- /dev/null +++ b/app/src/main/res/drawable/shape_icon_choose_no_select.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_icon_choose_select.xml b/app/src/main/res/drawable/shape_icon_choose_select.xml new file mode 100644 index 0000000..a79a5ec --- /dev/null +++ b/app/src/main/res/drawable/shape_icon_choose_select.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/work_add_bg.xml b/app/src/main/res/drawable/work_add_bg.xml new file mode 100644 index 0000000..5637c70 --- /dev/null +++ b/app/src/main/res/drawable/work_add_bg.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/work_delete.xml b/app/src/main/res/drawable/work_delete.xml new file mode 100644 index 0000000..b1e3b46 --- /dev/null +++ b/app/src/main/res/drawable/work_delete.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/work_round_top_white_15.xml b/app/src/main/res/drawable/work_round_top_white_15.xml new file mode 100644 index 0000000..8178068 --- /dev/null +++ b/app/src/main/res/drawable/work_round_top_white_15.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml new file mode 100644 index 0000000..c6fa95e --- /dev/null +++ b/app/src/main/res/layout/activity_about.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_app_guide_details.xml b/app/src/main/res/layout/activity_app_guide_details.xml new file mode 100644 index 0000000..ab3b9c0 --- /dev/null +++ b/app/src/main/res/layout/activity_app_guide_details.xml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_application_guide.xml b/app/src/main/res/layout/activity_application_guide.xml new file mode 100644 index 0000000..8d0b428 --- /dev/null +++ b/app/src/main/res/layout/activity_application_guide.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_apply_details.xml b/app/src/main/res/layout/activity_apply_details.xml new file mode 100644 index 0000000..f0b4b6e --- /dev/null +++ b/app/src/main/res/layout/activity_apply_details.xml @@ -0,0 +1,446 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ +

+ +

+ +

+ +

+ + +

+ +

+ +

+ + +

+ +

+ +

+ +

+ + + + \ No newline at end of file diff --git a/testwebview/src/main/assets/font/STXINGKA.TTF b/testwebview/src/main/assets/font/STXINGKA.TTF new file mode 100644 index 0000000..53439a2 Binary files /dev/null and b/testwebview/src/main/assets/font/STXINGKA.TTF differ diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/MyTextView.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/MyTextView.java new file mode 100644 index 0000000..00c62fc --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/MyTextView.java @@ -0,0 +1,32 @@ +package com.ruansee.macall.testwebview; + +import android.content.Context; +import android.graphics.Typeface; +import android.util.AttributeSet; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.jetbrains.annotations.NotNull; + +public class MyTextView extends androidx.appcompat.widget.AppCompatTextView { + + + public MyTextView(@NonNull @NotNull Context context) { + super(context); + Typeface type = Typeface.createFromAsset(context.getAssets(), "font/STXINGKA.TTF"); + setTypeface(type); + } + + public MyTextView(@NonNull @NotNull Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs) { + super(context, attrs); + Typeface type = Typeface.createFromAsset(context.getAssets(), "font/STXINGKA.TTF"); + setTypeface(type); + } + + public MyTextView(@NonNull @NotNull Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + Typeface type = Typeface.createFromAsset(context.getAssets(), "font/STXINGKA.TTF"); + setTypeface(type); + } +} diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/activity/MainActivity.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/activity/MainActivity.java new file mode 100644 index 0000000..dd82486 --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/activity/MainActivity.java @@ -0,0 +1,100 @@ +package com.ruansee.macall.testwebview.activity; + +import androidx.annotation.Nullable; + +import android.content.Intent; +import android.os.Bundle; +import android.view.View; + +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ruansee.macall.testwebview.app.AppCacheData; +import com.ruansee.macall.testwebview.app.RuanseeApp; +import com.ruansee.macall.testwebview.databinding.ActivityMainBinding; + +public class MainActivity extends BaseViewBindActivity { + + @Override + protected ActivityMainBinding getViewBinding() { + return ActivityMainBinding.inflate(getLayoutInflater()); + } + + @Override + protected void init() { + + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void start() { + setInitData(); + } + + private void setInitData() { + AppCacheData appCacheData = RuanseeApp.getAppCacheData(); + if (appCacheData == null){ + appCacheData = AppCacheData.getCacheData(); + } + if (!appCacheData.isUserEffective()){ + ToastUtil.centered(getContext(),"无效用户,请先设置用户新!"); + onSkipSetting(null); + return; + } + viewBinding.mainUserName.setText(String.format("%s(%s)",appCacheData.getUserName(),appCacheData.getDeptCode())); + viewBinding.mainDeptName.setText(StringUtil.get(appCacheData.getDeptName(),appCacheData.getDeptCode())); + String idCardNum = appCacheData.getIdCardNum(); + if (StringUtil.isNullOrEmpty(idCardNum)){ + viewBinding.mainUserSfzh.setText("暂无"); + }else { + char[] chars = idCardNum.toCharArray(); + //3424221993 0 6 0 4 1 4 1 3 + //0123456789 10 11 12 13 14 15 + StringBuilder builder = new StringBuilder(); + for (int i = 0; i = 8 && i<=14){ + builder.append("*"); + continue; + } + builder.append(chars[i]); + } + viewBinding.mainUserSfzh.setText(builder.toString()); + } + viewBinding.mainAppName.setText(appCacheData.getAppName()); + } + + public void onStartTest(View view){ + AppCacheData appCacheData = RuanseeApp.getAppCacheData(); + Intent intent = new Intent(getContext(), OpenAppActivity.class); + intent.putExtra(OpenAppActivity.paramKey1, appCacheData.getClientId()); + intent.putExtra(OpenAppActivity.paramKey2, appCacheData.getClientSecret()); + intent.putExtra(OpenAppActivity.paramKey3, appCacheData.getAppUrl()); + intent.putExtra(OpenAppActivity.paramKey9, appCacheData.getAppName()); + intent.putExtra(OpenAppActivity.paramKey10, "管理员"); + intent.putExtra(OpenAppActivity.paramKey11, "18888686866"); + startActivity(intent); + } + + public void onSkipSetting(View view){ + Intent intent = new Intent(getContext(), SettingActivity.class); + startActivity(intent); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable @org.jetbrains.annotations.Nullable Intent data) { + if (resultCode == 5151){ + //重新加载用户信息和应用信息 + setInitData(); + } + super.onActivityResult(requestCode, resultCode, data); + } +} \ No newline at end of file diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/activity/OpenAppActivity.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/activity/OpenAppActivity.java new file mode 100644 index 0000000..54428c8 --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/activity/OpenAppActivity.java @@ -0,0 +1,915 @@ +package com.ruansee.macall.testwebview.activity; + +import android.Manifest; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.location.Location; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.JavascriptInterface; +import android.webkit.WebSettings; +import android.widget.LinearLayout; + +import androidx.lifecycle.Lifecycle; + +import com.google.gson.Gson; +import com.just.agentweb.AgentWeb; +import com.just.agentweb.AgentWebConfig; +import com.just.agentweb.DefaultWebClient; +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.callback.PermissionListener; +import com.rs.macall.androidx.basemodel.utils.HandlerUtils; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StatusBarUtil; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ruansee.macall.testwebview.BuildConfig; +import com.ruansee.macall.testwebview.R; +import com.ruansee.macall.testwebview.app.AppCacheData; +import com.ruansee.macall.testwebview.app.CrashHandler; +import com.ruansee.macall.testwebview.app.GPSLocationListener; +import com.ruansee.macall.testwebview.app.RuanseeApp; +import com.ruansee.macall.testwebview.app.WebActivityCallback; +import com.ruansee.macall.testwebview.app.WebViewPresenter; +import com.ruansee.macall.testwebview.databinding.ActivityOpenAppBinding; +import com.ruansee.macall.testwebview.model.SelectFileOptions; +import com.ruansee.macall.testwebview.provider.DownloadUtil; +import com.ruansee.macall.testwebview.utils.FileUtils; +import com.ruansee.macall.testwebview.utils.JiaMi; +import com.ruansee.macall.testwebview.utils.LocationGPSManage; +import com.ruansee.macall.unifyservemodulesdk.ErrorMsg; +import com.ruansee.macall.unifyservemodulesdk.USMComponentSDK; +import com.ruansee.macall.unifyservemodulesdk.USMConfigure; +import com.ruansee.macall.unifyservemodulesdk.USMListener; +import com.ruansee.macall.unifyservemodulesdk.bean.CarOcrDataBean; +import com.ruansee.macall.unifyservemodulesdk.bean.ComponentBaseBean; +import com.ruansee.macall.unifyservemodulesdk.bean.FaceIdentifyBean; +import com.ruansee.macall.unifyservemodulesdk.bean.NFCBean; +import com.ruansee.macall.unifyservemodulesdk.bean.OcrSfzBean; + +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.net.URLDecoder; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OpenAppActivity extends BaseViewBindActivity implements PermissionListener { + private WebViewPresenter webViewPresenter; + /*统一服务组件SDK*/ + private USMComponentSDK usComponentSDK; + private AndroidMethodInterface androidMethodInterface; + private Handler myHandler; +// private CalculateInterface calculateInterface; + + ///////////////// 接收参数的KEY ////////////////// + /*第三方应用appId*/ + public static final String paramKey9 = "appName"; + /*第三方应用appId*/ + public static final String paramKey1 = "APPId"; + /*第三方应用的秘钥 */ + public static final String paramKey2 = "secret"; + /*第三方应用的链接地址*/ + public static final String paramKey3 = "LinkUrl"; + /*第三方应用对应的消息ID*/ + public static final String paramKey4 = "msgId"; + /*第三方应用对应的消息类型:当有的应用有多个消息类型时根据此参数判断*/ + public static final String paramKey5 = "msgType"; + /*第三方应用的操作类型 默认为 :login ,查看消息为: readMessage 查看搜索内容为:search */ + public static final String paramKey6 = "operationType"; + /*搜索类型 car / person*/ + public static final String paramKey7 = "searchType"; + /*搜索得到的数据Json 格式 */ + public static final String paramKey8 = "searchJson"; + + /*搜 联系人 */ + public static final String paramKey10 = "ywry"; + /*联系人电话 */ + public static final String paramKey11 = "ywrylxdh"; + + ///////////////// 接收参数的KEY ////////////////// + + private AgentWeb mAgentWeb; + private String appID; + private String secret, appName; + private String msgId, msgType, operationType; + private String searchType, searchJson; + private String intoUrl = "http://20.90.1.150:8888/"; + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected ActivityOpenAppBinding getViewBinding() { + return ActivityOpenAppBinding.inflate(getLayoutInflater()); + } + + @Override + protected void init() { + Log.w(TAG, "init"); + webViewPresenter = new WebViewPresenter(getContext(), new WebActivityCallback() { + @Override + public void onShowOperationSelectDialog(String[] split, int whit) { + webViewPresenter.onShowOperationSelectDialog(getActivity(), whit, split); + } + + @Override + public void onFinish() { + finish(); + } + }); + //统一服务组件 +// USMConfigure.getDefault().init("16854", "stegst"); + viewBinding.tvTestJs.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + mAgentWeb.getJsAccessEntrace().quickCallJs("callErrorResult", operationType, "test", "aseg"); +// mAgentWeb.getJsAccessEntrace().quickCallJs("callJS","a"); + } + }); + androidMethodInterface = new AndroidMethodInterface(); + viewBinding.titleleft.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + androidMethodInterface.onBack(); + } + }); + viewBinding.titleright.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + androidMethodInterface.exitToHome(); + } + }); + viewBinding.btnRefresh.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + androidMethodInterface.reloadPage(); + } + }); + myHandler = HandlerUtils.getActivity(this); + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + Log.w(TAG, "readInstanceState"); + if (savedInstanceState == null) { + appID = getIntent().getStringExtra(paramKey1); + secret = getIntent().getStringExtra(paramKey2); + intoUrl = getIntent().getStringExtra(paramKey3); + msgId = getIntent().getStringExtra(paramKey4); + msgType = getIntent().getStringExtra(paramKey5); + operationType = getIntent().getStringExtra(paramKey6); + appName = getIntent().getStringExtra(paramKey9); + searchType = getIntent().getStringExtra(paramKey7); + searchJson = getIntent().getStringExtra(paramKey8); + webViewPresenter.ywryName = getIntent().getStringExtra(paramKey10); + webViewPresenter.ywryPhone = getIntent().getStringExtra(paramKey11); + savePageCacheData(paramKey1, appID); + savePageCacheData(paramKey2, secret); + savePageCacheData(paramKey3, intoUrl); + savePageCacheData(paramKey4, msgId); + savePageCacheData(paramKey5, msgType); + savePageCacheData(paramKey6, operationType); + savePageCacheData(paramKey7, searchType); + savePageCacheData(paramKey8, searchJson); + savePageCacheData(paramKey9, appName); + savePageCacheData(paramKey10, webViewPresenter.ywryName); + savePageCacheData(paramKey11, webViewPresenter.ywryPhone); + } else { + appID = savedInstanceState.getString(paramKey1); + secret = savedInstanceState.getString(paramKey2); + intoUrl = savedInstanceState.getString(paramKey3); + msgId = savedInstanceState.getString(paramKey4); + msgType = savedInstanceState.getString(paramKey5); + operationType = savedInstanceState.getString(paramKey6); + appName = savedInstanceState.getString(paramKey9); + searchType = savedInstanceState.getString(paramKey7); + searchJson = savedInstanceState.getString(paramKey8); + webViewPresenter.ywryName = savedInstanceState.getString(paramKey10); + webViewPresenter.ywryPhone = savedInstanceState.getString(paramKey11); + } + usComponentSDK = USMConfigure.getDefault().getUsmComponentSDK(appID, secret); + viewBinding.contentTitle.setText(appName); + handInit(); + } + + @Override + protected void start() { + Log.w(TAG, "start"); +// initService(); + initWebView(); + usComponentSDK.setUSMListener(uscListener); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + requestPermissions(needPermissions, this); + } else { + initData(); + } + } + + private void initData() { + FileUtils.initFilePath(getContext()); + createFileDir(FileUtils.FILE_DIR); + createFileDir(FileUtils.DB_DIR); + createFileDir(FileUtils.DOWNLOADS_DIR); + createFileDir(FileUtils.IMAGE_DIR); + createFileDir(FileUtils.VOID_DIR); + createFileDir(FileUtils.LOG_DIR); + Log.w("Log目录", FileUtils.LOG_DIR); + CrashHandler.getInstance().init(getApplication(), FileUtils.LOG_DIR); + + String url = getUrl(); + LogUtils.d(TAG, url); +// mAgentWeb.getUrlLoader().loadUrl("file:///android_asset/TestJs.html"); + mAgentWeb.getUrlLoader().loadUrl(url); + } + + @Override + public void handleMessage(Message msg) { + if (msg.what == -55) {//刷新頁面 + if (!isDestroyed() && mAgentWeb != null) { + mAgentWeb.getWebCreator().getWebView().reload(); + return; + } + } + if (msg.what == -101) { + baseDismissDialog(); + return; + } + if (msg.what == 200) { + downFileError("下载成功!", "文件下载成功!"); + myHandler.sendEmptyMessageDelayed(103,800); + return; + } + if (msg.what == -200) { + downFileError("下载失败!", msg.obj+""); + return; + } + if (msg.what == 102) { + downFileError("文件下载中!", msg.obj+""); + return; + } + if (msg.what == 103) { + downDiag.dismiss(); + } + + } + + @Override + protected void onPause() { + if (mAgentWeb.getWebCreator() != null) { + mAgentWeb.getWebLifeCycle().onPause(); + } + super.onPause(); + } + + @Override + protected void onResume() { +// if (mResultCode == Activity.RESULT_CANCELED && isPermissionRequest) { +// try { +// if (mUploadMessageLollipop != null) { +// mUploadMessageLollipop.onReceiveValue(null); +// } +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } + if (mAgentWeb.getWebCreator() != null) { + mAgentWeb.getWebLifeCycle().onResume(); + } + super.onResume(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + Log.w(TAG, "onDestroy"); + AgentWebConfig.clearDiskCache(this.getContext()); + LocationGPSManage.getInstance().stopLocation(); + if (mAgentWeb.getWebCreator() != null) { + mAgentWeb.getWebLifeCycle().onDestroy(); + } + androidMethodInterface = null; + appID = ""; + secret = ""; +// if (mConn != null) { +// unbindService(mConn); +// } + } + + /** + * 绑定远程服务RemoteService + */ +// private void initService() { +// Log.w(TAG, "initService"); +// Intent intent = new Intent(getContext(), RemoteService.class); +//// intent.setComponent(new ComponentName("com.hongri.webview", "com.hongri.webview.service.RemoteService")); +// bindService(intent, mConn, BIND_AUTO_CREATE); +// } +// +// private final ServiceConnection mConn = new ServiceConnection() { +// @Override +// public void onServiceConnected(ComponentName name, IBinder service) { +//// Log.w(TAG, "onServiceConnected"); +// //当Service绑定成功时,通过Binder获取到远程服务代理 +// calculateInterface = CalculateInterface.Stub.asInterface(service); +// +// String url = getUrl(); +// LogUtils.d(TAG, url); +//// mAgentWeb.getUrlLoader().loadUrl("file:///android_asset/TestJs.html"); +// mAgentWeb.getUrlLoader().loadUrl(url); +// } +// +// @Override +// public void onServiceDisconnected(ComponentName name) { +//// Log.d(TAG, "onServiceDisconnected"); +// calculateInterface = null; +// } +// }; + private void createFileDir(String fileDirName) { + File file = new File(fileDirName); + if (file.exists()) return; + file.mkdirs(); + } + + private void handInit() { + if (StringUtil.isNullOrEmpty(operationType)) { + operationType = "login"; + } + if (StringUtil.isNullOrEmpty(intoUrl)) { + intoUrl = "https://www.baidu.com/my/index"; + } + webViewPresenter.intoUrl = intoUrl; + } + + private void showJimi(String... content) { + StringBuilder builder = new StringBuilder(); + String sp = ""; + for (String cont : content) { + builder.append(sp); + builder.append(cont); + sp = "\n"; + } + new AlertDialog.Builder(getContext()) + .setTitle("加密解密信息") + .setMessage(builder.toString()) + .create() + .show(); + } + + private String getUrl() { + StringBuilder builder = new StringBuilder(); + builder.append(intoUrl); + if (intoUrl.contains("?")) { + builder.append("&userInfo="); + } else { + builder.append("?userInfo="); + } + String userInfo = new AndroidMethodInterface().getUserInfo(); + try { + String decrypt1 = JiaMi.decrypt(userInfo, appID, secret); + showJimi("加密内容:" + userInfo, "id:" + appID, "secret:" + secret, "解密后:" + decrypt1); + LogUtils.w("解密", decrypt1); + } catch (Exception e) { + e.printStackTrace(); + } + builder.append(userInfo); + if (operationType.equals("readMessage")) { + if (StringUtil.hasContent(msgId)) { + builder.append("&operation_type=readMessage"); + builder.append("&msg_id="); + builder.append(msgId); + if (StringUtil.hasContent(msgType)) { + builder.append("&msg_type="); + builder.append(msgType); + } + } else { + builder.append("&operation_type=login"); + } + } else if (operationType.equals("search")) { + builder.append("&search_type="); + builder.append(searchType); + builder.append("&operation_type=search"); + } else { + builder.append("&operation_type=login"); + } + return builder.toString(); + } + + private void initWebView() { + mAgentWeb = AgentWeb.with(getActivity()) + .setAgentWebParent(viewBinding.viewGroup, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)) + .useDefaultIndicator() + .setWebViewClient(webViewPresenter.mWebViewClient) + .setWebChromeClient(webViewPresenter.mWebChromeClient) + .setSecurityType(AgentWeb.SecurityType.STRICT_CHECK) + .setOpenOtherPageWays(DefaultWebClient.OpenOtherPageWays.DISALLOW)//打开其他应用时,弹窗咨询用户是否前往其他应用 + .addJavascriptInterface(androidMethodInterface.toName(), androidMethodInterface) + .createAgentWeb() + .ready().get(); + WebSettings webSettings = mAgentWeb.getAgentWebSettings().getWebSettings(); + webSettings.setJavaScriptEnabled(true); + webSettings.setDomStorageEnabled(true); +// webSettings.setLoadWithOverviewMode(true); +// webSettings.setLoadsImagesAutomatically(true); + webSettings.setBlockNetworkImage(false); +// webSettings.setJavaScriptCanOpenWindowsAutomatically(true); + webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); + + // 设置支持本地存储 +// webSettings.setDatabaseEnabled(true); +// //设置存储模式 +// webSettings.setCacheMode(WebSettings.LOAD_DEFAULT); +// webSettings.setAppCacheEnabled(true); + + + mAgentWeb.getWebCreator().getWebView().setHorizontalScrollBarEnabled(false); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && BuildConfig.DEBUG) { + mAgentWeb.getWebCreator().getWebView().setWebContentsDebuggingEnabled(true); + } + + mAgentWeb.getWebCreator().getWebView().setDownloadListener((url1, userAgent, contentDisposition, mimetype, contentLength) -> { + ToastUtil.centered(getContext(), "下载监听被触发,请求地址:" + url1); + if (StringUtil.isNullOrEmpty(url1)) { + ToastUtil.centered(getContext(), "下载链接为空,请检查链接是否真实!"); + return; + } + String s1 = url1.toLowerCase(); + if (!s1.startsWith("http://") && !s1.startsWith("https://")) { + ToastUtil.centered(getContext(), "URL缺少请求头,将默认使用Http协议下载"); + url1 = "http://" + url1; + } + + String fileName = ""; + if (StringUtil.hasContent(contentDisposition)) { + String[] split = contentDisposition.split("="); + fileName = split[split.length - 1]; + } + if (StringUtil.isNullOrEmpty(fileName)) { + fileName = url1.substring(url1.lastIndexOf("/") + 1); + } + String jm = URLDecoder.decode(fileName); + if (fileName.length() > jm.length()) { + fileName = jm; + } + fileName = fileName.replace("/","_").replace("\\","_"); + + String s = FileUtils.DOWNLOADS_DIR + fileName; + File file = new File(s); + //打开文件 + if (file.exists()) + FileUtils.openFileByPath(getActivity(), file.getAbsolutePath()); + else { + downFileError("下载文件", "开始下载:" + fileName); +// baseShowFaseDialog("温馨提示", String.format("正在下载'%s',请稍后...", fileName)); + webViewPresenter.downloadFile(url1, fileName, new DownloadUtil.OnDownloadListener() { + @Override + public void onDownloadSuccess(File file) { + lastProgress = 0; + myHandler.sendEmptyMessage(-101); + if (file.exists()) { + //打开文件 + myHandler.obtainMessage(200, "文件下载成功!").sendToTarget(); +// downFileError("下载成功!", "文件下载成功!"); +// ToastUtil.centered(getContext(), "文件下载成功!"); + FileUtils.openFileByPath(getActivity(), file.getAbsolutePath()); + } else { + myHandler.obtainMessage(-200, "文件保存失败!").sendToTarget(); +// downFileError("下载失败!", "文件报错失败!"); +// ToastUtil.centered(getContext(), "文件下载失败!"); + } + } + + @Override + public void onDownloading(int progress) { + if (progress == lastProgress){ + return; + } + lastProgress = progress; + myHandler.obtainMessage(102, "开始下载进度:" + lastProgress + "%").sendToTarget(); +// downFileError("下载文件","开始下载进度:"+progress+"%s"); + } + + @Override + public void onDownloadFailed(String msg) { + lastProgress = 0; + myHandler.sendEmptyMessage(-101); + myHandler.obtainMessage(-200, msg).sendToTarget(); +// downFileError("下载失败!", msg); +// ToastUtil.centered(getContext(), "文件下载失败:" + msg); + } + }); + } + }); + } + private int lastProgress = 0; + + private AlertDialog downDiag; + + private void downFileError(String title, String msg) { + if (downDiag == null) { + downDiag = new AlertDialog.Builder(getContext()) + .setTitle(title) + .setMessage(msg) + .setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }).create(); + } + if (!downDiag.isShowing()) { + downDiag.show(); + } + downDiag.setMessage(msg); + downDiag.setTitle(title); + } + + private final USMListener uscListener = new USMListener() { + @Override + public void onUSCSuccess(String operationType, ComponentBaseBean resultBean) { + LogUtils.d(TAG, operationType); + if (resultBean == null) { + ToastUtil.centered(getContext(), "错误的返回值!"); + mAgentWeb.getJsAccessEntrace().quickCallJs("callErrorResult", operationType, String.valueOf(ErrorMsg.ERROR_RESULT.getIndex()), ErrorMsg.ERROR_RESULT.getName()); + return; + } + if (resultBean instanceof NFCBean) { + NFCBean bean = (NFCBean) resultBean; + ToastUtil.centered(getContext(), "NFC返回:" + bean.getName()); + mAgentWeb.getJsAccessEntrace().quickCallJs("callNFCResult", new Gson().toJson(bean)); + return; + } + if (resultBean instanceof FaceIdentifyBean) { + FaceIdentifyBean bean = (FaceIdentifyBean) resultBean; + ToastUtil.centered(getContext(), "人像:" + bean.getName()); + mAgentWeb.getJsAccessEntrace().quickCallJs("callFaceIdentifyResult", new Gson().toJson(bean)); + return; + } + if (resultBean instanceof OcrSfzBean) { + OcrSfzBean bean = (OcrSfzBean) resultBean; + ToastUtil.centered(getContext(), "OCR身份证返回:" + bean.getName()); + mAgentWeb.getJsAccessEntrace().quickCallJs("callCORSfzResult", new Gson().toJson(bean)); + return; + } + if (resultBean instanceof CarOcrDataBean) { + CarOcrDataBean bean = (CarOcrDataBean) resultBean; + ToastUtil.centered(getContext(), "OCRCar返回:" + bean.getData().get(0).getPlateNumber()); + mAgentWeb.getJsAccessEntrace().quickCallJs("callOCRCarResult", new Gson().toJson(bean)); + } + } + + @Override + public void onUSCError(String operationType, int code, String msg) { + if (ErrorMsg.ERROR_USER_CANCEL.getIndex() != code) { + ToastUtil.centered(getContext(), String.format("错误码%s || %s", code, msg)); + } + mAgentWeb.getJsAccessEntrace().quickCallJs("callErrorResult", operationType, String.valueOf(code), msg); + } + }; + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + usComponentSDK.onActivityResult(requestCode, resultCode, data); + if (resultCode == Activity.RESULT_OK) { + if (null == webViewPresenter.mFilePathCallback) return; + switch (requestCode) { + case WebViewPresenter.RESULT_CODE: + if (webViewPresenter.photoFile == null || !webViewPresenter.photoFile.exists()) + return; + webViewPresenter.ysBitmap(); + return; + case WebViewPresenter.SELECT_IMG_CODE: + case WebViewPresenter.SELECT_FILE_CODE: + webViewPresenter.onActivityResultAboveL(requestCode, resultCode, data); + return; + } + } + if (webViewPresenter.mFilePathCallback != null) { + webViewPresenter.onActivityResultAboveL(requestCode, resultCode, data); +// webViewPresenter.mFilePathCallback.onReceiveValue(null); + webViewPresenter.mFilePathCallback = null; + return; + } + super.onActivityResult(requestCode, resultCode, data); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (mAgentWeb.handleKeyEvent(keyCode, event)) + return true; + return super.onKeyDown(keyCode, event); + } + + private GPSLocationListener gpsLocationListener; + + private GPSLocationListener getGPSLocationListener() { + return new GPSLocationListener() { + @Override + public void onLocationChanged(Location location) { + ToastUtil.centered(getContext(), "调用位置更新" + location.toString()); + mAgentWeb.getJsAccessEntrace().quickCallJs("callLocationResult", location.getLongitude() + "", location.getLatitude() + ""); + } + + @Override + public void stopLocation() { + ToastUtil.centered(getContext(), "调用停止位置更新"); + if (mAgentWeb == null) return; + try { + mAgentWeb.getJsAccessEntrace().quickCallJs("callLocationError", "-102", "停止定位"); + } catch (Exception e) { + e.printStackTrace(); + ToastUtil.centered(getContext(), "ERROR:" + e.getMessage()); + finish(); + } + } + }; + } + + /** + * 需要进行检测的权限数组 + */ + protected String[] needPermissions = { + Manifest.permission.CAMERA, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CALL_PHONE, + Manifest.permission.ACCESS_NETWORK_STATE + }; + + @Override + public void onGranted() { + initData(); + } + + @Override + public void onDenied(List deniDPermission) { + showMissingPermissionDialog(); + } + + private class AndroidMethodInterface { + + @JavascriptInterface + public void startLocation() { + LocationGPSManage manage = LocationGPSManage.getInstance(); + if (gpsLocationListener == null) { + gpsLocationListener = getGPSLocationListener(); + } + manage.addGPSLocationListener(gpsLocationListener); + try { + manage.startGPSLocation(getContext()); + } catch (RuntimeException e) { + ToastUtil.centered(getContext(), "没有权限,请先授权定位权限!"); + showMissingPermissionDialog(); + } + } + + @JavascriptInterface + public void stopLocation() { +// ToastUtil.centered(getContext(),"H5调用了停止定位"); + LocationGPSManage manage = LocationGPSManage.getInstance(); + if (gpsLocationListener == null) { + gpsLocationListener = getGPSLocationListener(); + } + manage.removeGPSLocationListener(gpsLocationListener); + manage.stopLocation(); + } + + /** + * 获取用户信息,为Base64转码的Json对象 + * Json格式:{"userCode":"警号","userName":"姓名","idCardNum":"身份证号","deptCode":"组织机构代码","deptName":"组织机构代码名称"} + */ + @JavascriptInterface + public String getUserInfo() { +// try { +// return calculateInterface.getJiaMi(appID, secret); +// } catch (RemoteException e) { +// e.printStackTrace(); +// return ""; +// } + AppCacheData userData = RuanseeApp.getAppCacheData(); + Map param = new HashMap<>(); + param.put("userCode", userData.getUserCode()); + param.put("userName", userData.getUserName()); + param.put("idCardNum", userData.getIdCardNum()); + param.put("deptCode", userData.getDeptCode()); + param.put("deptName", userData.getDeptName()); + String s = new Gson().toJson(param); + return JiaMi.desCrypto(s.getBytes(), appID, secret); + } + + /** + * 配置上传文件选择项。此方法再调用上传文件的事件之前调用,如果不调用则默认 selfRealization = false , 其他参数默认为 true + * + * @param selfRealization 是否由JS自己实现文件选择上传。 + * PS: true:由JS自己实现,Android原生不做操作,不会弹出选择框,.值为false时将原生代码将拦截操作并根据下面参数配置弹出选择框。 + * @param isCamera PS:是否支持相机拍照: true = 支持相机拍照上传,false = 不支持相机拍照上传,值为false时弹出框将没有相机选项 + * @param isDCIM PS:是否支持相册选择: true = 支持相册选择上传,false = 不支持相册选择上传,值为false时弹出框将没有相册选项 + * @param isFileSelection PS:是否支持文件选择: true = 支持文件选择上传,false = 不支持文件选择上传,值为false时弹出框将没有文件选择选项 + */ + @JavascriptInterface + public void setUploadFileOptions(boolean selfRealization, boolean isCamera, boolean isDCIM, boolean isFileSelection) { + if (webViewPresenter.selectFileOptions == null) { + webViewPresenter.selectFileOptions = new SelectFileOptions(selfRealization, isCamera, isDCIM, isFileSelection); + } else { + webViewPresenter.selectFileOptions.configureOptions(selfRealization, isCamera, isDCIM, isFileSelection); + } + } + + /** + * 调用返回按钮 + */ + @JavascriptInterface + public void onBack() { + if (mAgentWeb.back()) return; + finish(); + } + + /** + * 控制APP标题栏显示隐藏 + * + * @param isShow true = 显示 || false = 隐藏 + */ + @JavascriptInterface + public void isTitleBlock(boolean isShow) { + isTitleBlock(isShow, false); + } + + + /** + * 控制APP标题栏显示隐藏 + * + * @param isShow true = 显示 || false = 隐藏 + */ + @JavascriptInterface + public void isTitleBlock(boolean isShow, boolean showMsg) { + if (isShow) { + visibleView(viewBinding.baseTitle); + if (showMsg) { + visibleView(viewBinding.btnMsg); + setViewOnClickListener(viewBinding.btnMsg); + } else { + goneView(viewBinding.btnMsg); + } + } else { + goneView(viewBinding.baseTitle); + } + } + + /** + * 退出到主页 + */ + @JavascriptInterface + public void exitToHome() { + finish(); + } + + /** + * 设置状态栏颜色及状态栏图标字体颜色深浅模式 + * + * @param statusBarColor 状态栏颜色 值为字符串 格式为:#ffffff + * @param isBlackFontColor 是否为 true 为黑色字体 | false 为白色字体 + */ + @JavascriptInterface + public void setSystemStatusBarStyle(String statusBarColor, boolean isBlackFontColor) { + int i = strToTextColor(statusBarColor, "#3255E3"); + runOnUiThread(new Runnable() { + @Override + public void run() { + StatusBarUtil.setStatusBarColor(getActivity(), i, isBlackFontColor); + try { + ColorDrawable drawable = new ColorDrawable(i); + viewBinding.vTopSeize.setBackground(drawable); + viewBinding.baseTitle.setBackground(drawable); + if (isBlackFontColor) { + viewBinding.contentTitle.setTextColor(getColors(R.color.colorGrey8)); + viewBinding.btnMsg.setImageDrawable(getDrawable(R.drawable.icon_msg_ld_back)); + viewBinding.leftImage.setImageDrawable(getDrawables(R.drawable.ic_back_b)); + viewBinding.rightImage.setImageDrawable(getDrawables(R.drawable.icon_over_back)); + viewBinding.btnRefresh.setImageDrawable(getDrawables(R.drawable.icon_refresh_grad)); + } else { + viewBinding.contentTitle.setTextColor(getColors(R.color.colorWhite)); + viewBinding.leftImage.setImageDrawable(getDrawables(R.drawable.back_cliener)); + viewBinding.rightImage.setImageDrawable(getDrawables(R.drawable.icon_over)); + viewBinding.btnRefresh.setImageDrawable(getDrawables(R.drawable.icon_refresh)); + viewBinding.btnMsg.setImageDrawable(getDrawable(R.drawable.icon_msg_ld_white)); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + /** + * @color:后台返回的色值 + * @defaultColor:ui默认的色值 + */ + private int strToTextColor(String color, String defaultColor) { + if (StringUtil.isNullOrEmpty(color)) { + return Color.parseColor(defaultColor); + } + if (!StringUtil.isNullOrEmpty(color) && (color.length() == 7) && (color.startsWith("#"))) { + return Color.parseColor(color); + } else { + return Color.parseColor(defaultColor); + } + } + + @JavascriptInterface + public String toName() { + return "callByAndroid"; + } + + /** + * 弹出提示框 + * + * @param title 提示标题 + * @param msg 提示内容 + * @param lxryName 联系人员 + * @param lxryPhone 联系电话 + */ + @JavascriptInterface + public void showNetPermission(String title, String msg, String lxryName, String lxryPhone) { + webViewPresenter.showLoadWebError(title, msg, lxryName, lxryPhone); + } + + @JavascriptInterface + public void reloadPage() { + reloadPageAndroid(); + } + + /** + * 刷新页面 + */ + private void reloadPageAndroid() { + if (mAgentWeb == null) return; + //拿到这个页面,最后一次加载的url + String lastLoadUrl = mAgentWeb.getWebCreator().getWebView().getUrl(); + LogUtils.w("最后加载链接", lastLoadUrl); + //停止上次刷新 + mAgentWeb.getUrlLoader().stopLoading(); +// AgentWebConfig.removeAllCookies(); + AgentWebConfig.clearDiskCache(getContext()); + mAgentWeb.getUrlLoader().loadUrl(lastLoadUrl); + if (myHandler != null && lastLoadUrl != null) { + myHandler.sendEmptyMessageDelayed(-55, 50); + } + } + + /** + * 打开人像比对 + */ + @JavascriptInterface + public void goPersonFaceModule() { + ToastUtil.centered(getContext(), "Android 原生方法 goPersonFaceModule() 被调用,该功能将打开人像比对功能!"); + usComponentSDK.openFaceIdentifyComponent(OpenAppActivity.this); + } + + /** + * 打开NFC组件 + */ + @JavascriptInterface + public void goNFCModule() { + ToastUtil.centered(getContext(), "Android 原生方法 goNFCModule() 被调用,该功能将打开NFC识别功能!"); + usComponentSDK.openNFCComponent(OpenAppActivity.this); + } + + /** + * 打开OCR组件 + */ + @JavascriptInterface + public void goOCRCarModule() { + ToastUtil.centered(getContext(), "Android 原生方法 goOCRCarModule() 被调用,该功能将打开OCR车牌识别功能!"); + usComponentSDK.openOcrCarComponent(OpenAppActivity.this); + } + + /** + * 打开OCR组件 + */ + @JavascriptInterface + public void goOCRSfzModule() { + ToastUtil.centered(getContext(), "Android 原生方法 goOCRSfzModule() 被调用,该功能将打开OCR车牌识别功能!"); + usComponentSDK.openOcrSfzComponent(OpenAppActivity.this); + } + } + + +} \ No newline at end of file diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/activity/SettingActivity.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/activity/SettingActivity.java new file mode 100644 index 0000000..e199eb4 --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/activity/SettingActivity.java @@ -0,0 +1,108 @@ +package com.ruansee.macall.testwebview.activity; + +import android.content.Intent; +import android.os.Bundle; +import android.view.View; + +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ruansee.macall.testwebview.app.AppCacheData; +import com.ruansee.macall.testwebview.R; +import com.ruansee.macall.testwebview.app.RuanseeApp; +import com.ruansee.macall.testwebview.databinding.ActivitySettingBinding; + +public class SettingActivity extends BaseViewBindActivity { + private boolean isSkipMain = false; + + @Override + protected ActivitySettingBinding getViewBinding() { + return ActivitySettingBinding.inflate(getLayoutInflater()); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void init() { + + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + isSkipMain = getIntent().getBooleanExtra("isSkipMain", false); + } + + @Override + protected void start() { + viewBinding.include.contentTitle.setText("设置"); + viewBinding.include.leftImage.setImageDrawable(getDrawables(R.drawable.back_cliener)); + viewBinding.include.titleleft.setOnClickListener(v -> finish()); + setData(); + } + + private void setData() { + AppCacheData appCacheData = RuanseeApp.getAppCacheData(); + if (appCacheData == null) { + appCacheData = AppCacheData.getCacheData(); + } + + viewBinding.settingAppName.setText(appCacheData.getAppName()); + viewBinding.settingAppUrl.setText(appCacheData.getAppUrl()); + viewBinding.settingUserCode.setText(appCacheData.getUserCode()); + viewBinding.settingUserName.setText(appCacheData.getUserName()); + viewBinding.settingUserSfzh.setText(appCacheData.getIdCardNum()); + viewBinding.settingDeptCode.setText(appCacheData.getDeptCode()); + viewBinding.settingDeptName.setText(appCacheData.getDeptName()); + viewBinding.settingAppClientId.setText(appCacheData.getClientId()); + viewBinding.settingAppClientSecret.setText(appCacheData.getClientSecret()); + + } + + public void onSubmit(View view) { + String appName = getEditText(viewBinding.settingAppName); + String appUrl = getEditText(viewBinding.settingAppUrl); + String userCode = getEditText(viewBinding.settingUserCode); + String userName = getEditText(viewBinding.settingUserName); + String idCardName = getEditText(viewBinding.settingUserSfzh); + String deptCode = getEditText(viewBinding.settingDeptCode); + String deptName = getEditText(viewBinding.settingDeptName); + String clientId = getEditText(viewBinding.settingAppClientId); + String clientSecret = getEditText(viewBinding.settingAppClientSecret); + if (judge(userCode, "请输入用户警号")) return; + if (judge(userName, "请输入用户姓名")) return; + if (judge(idCardName, "请输入用户证件号码")) return; + if (judge(deptCode, "请输入用户机构代码")) return; + if (judge(appName, "请输入应用名称")) return; + if (judge(appUrl, "请输入应用地址")) return; + if (judge(clientId, "请输入clientId")) return; + if (judge(clientSecret, "请输入clientSecret")) return; + AppCacheData appCacheData = RuanseeApp.getAppCacheData(); + appCacheData.setAppName(appName); + appCacheData.setAppUrl(appUrl); + appCacheData.setDeptCode(deptCode); + appCacheData.setDeptName(deptName); + appCacheData.setIdCardNum(idCardName); + appCacheData.setUserCode(userCode); + appCacheData.setUserName(userName); + appCacheData.setClientId(clientId); + appCacheData.setClientSecret(clientSecret); + if (isSkipMain) { + startActivity(new Intent(getContext(), MainActivity.class)); + }else { + setResult(5151); + } + finish(); + } + + private boolean judge(String value, String titMsg) { + if (StringUtil.isNullOrEmpty(value)) { + ToastUtil.centered(getContext(), titMsg); + return true; + } + return false; + } + +} \ No newline at end of file diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/activity/StartActivity.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/activity/StartActivity.java new file mode 100644 index 0000000..51c9188 --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/activity/StartActivity.java @@ -0,0 +1,110 @@ +package com.ruansee.macall.testwebview.activity; + +import android.Manifest; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; + +import com.rs.macall.androidx.basemodel.base.BaseViewBindActivity; +import com.rs.macall.androidx.basemodel.callback.PermissionListener; +import com.rs.macall.androidx.basemodel.utils.HandlerUtils; +import com.ruansee.macall.testwebview.app.RuanseeApp; +import com.ruansee.macall.testwebview.databinding.ActivityStartBinding; + +import java.util.List; + +public class StartActivity extends BaseViewBindActivity implements PermissionListener { + + private Handler myHandler; + + private String[] permissionList = { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.CAMERA, + Manifest.permission.ACCESS_NETWORK_STATE}; + + @Override + protected ActivityStartBinding getViewBinding() { + return ActivityStartBinding.inflate(getLayoutInflater()); + } + + @Override + protected void init() { + myHandler = HandlerUtils.getActivity(this); + } + + @Override + protected boolean isImmersiveStatusBar() { + return true; + } + + @Override + protected void readInstanceState(Bundle savedInstanceState) { + + } + + @Override + protected void start() { + if (!this.isTaskRoot()) { + Intent mainIntent = getIntent(); + String action = mainIntent.getAction(); + if (mainIntent.hasCategory(Intent.CATEGORY_LAUNCHER) && action.equals(Intent.ACTION_MAIN)) { + finish(); + return; + } + } + viewBinding.tvMsg.setText("正在检测应用权限..."); + viewBinding.AVLoadingIndicatorView.smoothToShow(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + requestPermissions(permissionList, this); + } else { + initPage(); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + } + + private void initPage() { + viewBinding.tvMsg.setText("权限通过,正在验证用户信息..."); + myHandler.sendEmptyMessageDelayed(1, 1000); + } + + @Override + public void handleMessage(Message msg) { + if (msg.what == 1) { + if (!RuanseeApp.getAppCacheData().isUserEffective()) { + //无效 + viewBinding.tvMsg.setText("无效用户,请至设置用户信息..."); + myHandler.sendEmptyMessageDelayed(2, 1000); + } else { + viewBinding.tvMsg.setText("验证成功,正在跳转..."); + myHandler.sendEmptyMessageDelayed(3, 1000); + } + } else if (msg.what == 2) { + viewBinding.AVLoadingIndicatorView.smoothToHide(); + Intent intent = new Intent(getContext(), SettingActivity.class); + intent.putExtra("isSkipMain",true); + startActivity(intent); + finish(); + } else if (msg.what == 3) { + viewBinding.AVLoadingIndicatorView.smoothToHide(); + startActivity(new Intent(getContext(), MainActivity.class)); + finish(); + } + } + + @Override + public void onGranted() { + initPage(); + } + + @Override + public void onDenied(List deniDPermission) { + showMissingPermissionDialog(); + } +} \ No newline at end of file diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/app/AppCacheData.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/AppCacheData.java new file mode 100644 index 0000000..97a8829 --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/AppCacheData.java @@ -0,0 +1,159 @@ +package com.ruansee.macall.testwebview.app; + +import com.rs.macall.androidx.basemodel.utils.StringUtil; + +/** + * created by: Macall + * create time: 2023/12/7 9:20 + * copyright: @ruansee.com + * Describe: + */ +public class AppCacheData { + private static AppCacheData cacheData; + + private String userCode; + private String userName; + private String idCardNum; + private String deptCode; + private String deptName; + + private String appUrl; + + private String appName; + + private String clientId; + private String clientSecret; + + + private AppCacheData(){ + + } + + /** + * 用户信息是否有效 + * @return + */ + public boolean isUserEffective(){ + if (StringUtil.isContainEmpty(getUserCode(),getIdCardNum(),getDeptCode(),getClientId(),getClientSecret()))return false; + return true; + } + + public static AppCacheData getCacheData() { + if (cacheData ==null){ + synchronized (AppCacheData.class){ + if (cacheData == null){ + cacheData = new AppCacheData(); + } + } + } + return cacheData; + } + + public String getUserCode() { + if (StringUtil.isNullOrEmpty(userCode)){ + userCode = RuanseeApp.getStringValue("userCode"); + } + return userCode; + } + + public void setUserCode(String userCode) { + RuanseeApp.saveData("userCode",userCode); + this.userCode = userCode; + } + + public String getUserName() { + if (StringUtil.isNullOrEmpty(userName)){ + userName = RuanseeApp.getStringValue("userName"); + } + return userName; + } + + public void setUserName(String userName) { + RuanseeApp.saveData("userName",userName); + this.userName = userName; + } + + public String getIdCardNum() { + if (StringUtil.isNullOrEmpty(idCardNum)){ + idCardNum = RuanseeApp.getStringValue("idCardNum"); + } + return idCardNum; + } + + public void setIdCardNum(String idCardNum) { + RuanseeApp.saveData("idCardNum",idCardNum); + this.idCardNum = idCardNum; + } + + public String getDeptCode() { + if (StringUtil.isNullOrEmpty(deptCode)){ + deptCode = RuanseeApp.getStringValue("deptCode"); + } + return deptCode; + } + + public void setDeptCode(String deptCode) { + RuanseeApp.saveData("deptCode",deptCode); + this.deptCode = deptCode; + } + + public String getDeptName() { + if (StringUtil.isNullOrEmpty(deptName)){ + deptName = RuanseeApp.getStringValue("deptName"); + } + return deptName; + } + + public void setDeptName(String deptName) { + RuanseeApp.saveData("deptName",deptName); + this.deptName = deptName; + } + + public String getAppUrl() { + if (StringUtil.isNullOrEmpty(appUrl)){ + appUrl = RuanseeApp.getStringValue("appUrl"); + } + return appUrl; + } + + public void setAppUrl(String appUrl) { + this.appUrl = appUrl; + RuanseeApp.saveData("appUrl",appUrl); + } + + public String getAppName() { + if (StringUtil.isNullOrEmpty(appName)){ + appName = RuanseeApp.getStringValue("appName"); + } + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + RuanseeApp.saveData("appName",appName); + } + + public void setClientId(String clientId) { + this.clientId = clientId; + RuanseeApp.saveData("clientId",clientId); + } + + public String getClientSecret() { + if (StringUtil.isNullOrEmpty(clientSecret)){ + clientSecret = RuanseeApp.getStringValue("clientSecret"); + } + return clientSecret; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + RuanseeApp.saveData("clientSecret",clientSecret); + } + + public String getClientId() { + if (StringUtil.isNullOrEmpty(clientId)){ + clientId = RuanseeApp.getStringValue("clientId"); + } + return clientId; + } +} diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/app/CrashHandler.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/CrashHandler.java new file mode 100644 index 0000000..c84c307 --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/CrashHandler.java @@ -0,0 +1,216 @@ +package com.ruansee.macall.testwebview.app; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.os.Build; +import android.os.Environment; +import android.os.Looper; +import android.util.Log; + + +import com.ruansee.macall.testwebview.utils.FileUtils; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.lang.Thread.UncaughtExceptionHandler; +import java.lang.reflect.Field; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +public class CrashHandler implements UncaughtExceptionHandler { + + public static final String TAG = "CrashHandler"; + public static String LOG_DIR = FileUtils.FILE_DIR + "cache/log"; + private UncaughtExceptionHandler mDefaultHandler; + + private static CrashHandler INSTANCE = new CrashHandler(); + + private Context mContext; + + private Map infos = new HashMap(); + +// private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); + + private CrashHandler() { + } + + public synchronized static CrashHandler getInstance() { + if (INSTANCE == null){ + synchronized (CrashHandler.class){ + if (INSTANCE == null){ + INSTANCE = new CrashHandler(); + } + } + } + return INSTANCE; + } + + public void init(Context context,String LOG_DIR) { + mContext = context; + mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); + this.LOG_DIR = LOG_DIR; + Thread.setDefaultUncaughtExceptionHandler(this); + } + + @Override + public void uncaughtException(Thread thread, Throwable ex) { + if (!handleException(ex) && mDefaultHandler != null) { + mDefaultHandler.uncaughtException(thread, ex); + } else { + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + Log.e(TAG, "error : ", e); + } + android.os.Process.killProcess(android.os.Process.myPid()); + System.exit(1); + } + } + + private boolean handleException(Throwable ex) { + if (ex == null) { + return false; + } + final Throwable _ex = ex; + new Thread() { + @Override + public void run() { + Looper.prepare(); +// Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出" + _ex.getMessage(), Toast.LENGTH_LONG) +// .show(); + //TwitterApplication.LogOut(mContext); + Looper.loop(); + } + }.start(); + + // 收集设备参数信息 + collectDeviceInfo(mContext); + // 保存日志文件 + saveCrashInfo2File(ex); + return true; + } + + /** + * 收集设备参数信息 + * + * @param ctx + */ + public void collectDeviceInfo(Context ctx) { + try { + PackageManager pm = ctx.getPackageManager(); + PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), + PackageManager.GET_ACTIVITIES); + if (pi != null) { + String versionName = pi.versionName == null ? "null" + : pi.versionName; + String versionCode = pi.versionCode + ""; + infos.put("versionName", versionName); + infos.put("versionCode", versionCode); + } + } catch (NameNotFoundException e) { + Log.e(TAG, "an error occured when collect package info", e); + infos.put("Exception1:", "收集系统参数报错"); + } + Field[] fields = Build.class.getDeclaredFields(); + for (Field field : fields) { + try { + field.setAccessible(true); + infos.put(field.getName(), field.get(null).toString()); + Log.d(TAG, field.getName() + " : " + field.get(null)); + } catch (Exception e) { + Log.e(TAG, "an error occured when collect crash info", e); + infos.put("Exception2:", "收集系统参数报错"); + } + } + } + + private void saveCrashInfo2File(Throwable ex) { + StringBuffer sb = new StringBuffer(); + sb.append("================ 系统信息 ===================" + "\n"); + for (Map.Entry entry : infos.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + sb.append(key + "=" + value + "\n"); + } + sb.append("================ 系统信息 /===================" + "\n"); + sb.append("================ 报错信息 ===================" + "\n"); + Writer writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + Throwable cause = ex.getCause(); + while (cause != null) { + cause.printStackTrace(printWriter); + cause = cause.getCause(); + } + printWriter.close(); + String result = writer.toString(); + sb.append(result); + sb.append("================ 报错信息 ===================" + "\n"); + sendErrorLog(sb.toString()); + try { + long timestamp = System.currentTimeMillis() % 100000; + @SuppressLint("SimpleDateFormat") + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); + String time = sdf.format(new Date()); +// String time = formatter.from(new Date()); + String fileName = "WZT_" + time + "-" + timestamp + ".log"; + if (Environment.getExternalStorageState().equals( + Environment.MEDIA_MOUNTED)) { + String path = LOG_DIR; + File dir = new File(path); + if (!dir.exists()) { + dir.mkdirs(); + } + FileOutputStream fos = new FileOutputStream(path + "/" + fileName); + fos.write(sb.toString().getBytes()); + fos.close(); + } + } catch (Exception e) { + Log.e(TAG, "an error occured while writing file...", e); + } + } + + private void sendErrorLog(String errorText) { +// RequestModel.uploadOperationLog("5","2",errorText); +//// String url = "http://192.168.43.202:8081/ypc/phone/error/saveError"; +// String url = YcgisApplication.getAppCacheData().getApiBaseUrl()+"error/saveError"; +// YcgisApplication +// .componet() +// .environment() +// .apiClient() +// .saveErrorLog(url, YcgisApplication.getAppCacheData().getUserCode(), errorText) +// .subscribeOn(Schedulers.io()) +// .observeOn(Schedulers.io()) +// .subscribe(new Observer() { +// @Override +// public void onSubscribe(Disposable d) { +// Log.w(TAG, "onSubscribe " + d.toString()); +// } +// +// @Override +// public void onNext(JsonObject s) { +// Log.w(TAG, s.toString()); +// } +// +// @Override +// public void onError(Throwable e) { +// Log.e(TAG, "onError " + e.getMessage()); +// } +// +// @Override +// public void onComplete() { +// Log.w(TAG, "onComplete "); +// } +// }); + } + + +} diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/app/GPSListener.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/GPSListener.java new file mode 100644 index 0000000..5f969ca --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/GPSListener.java @@ -0,0 +1,12 @@ +package com.ruansee.macall.testwebview.app; + +import com.rs.macall.androidx.basemodel.utils.GpsUtil; + +/** + * created by: Macall + * create time: 2023/3/28 9:40 + * copyright: @ruansee.com + * Describe: + */ +public class GPSListener extends GpsUtil { +} diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/app/GPSLocationListener.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/GPSLocationListener.java new file mode 100644 index 0000000..2a474a1 --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/GPSLocationListener.java @@ -0,0 +1,51 @@ +package com.ruansee.macall.testwebview.app; + +import android.location.Location; + +/** + * created by: Macall + * create time: 2023/3/28 9:38 + * copyright: @ruansee.com + * Describe: + */ +public abstract class GPSLocationListener { + + /** + * 位置发生改变 + * @param location + */ + public abstract void onLocationChanged(Location location); + + public void stopLocation(){} + + public void onScanSatellite(int totalCount,int bduCount,int locationCount){} + +// /** +// * 定位状态发生改变 +// * @param provider +// * @param status +// * @param extras +// */ +// @Override +// public void onStatusChanged(String provider, int status, Bundle extras) { +// +// } +// +// /** +// * 启用 定位模式 +// * @param provider +// */ +// @Override +// public void onProviderEnabled(String provider) { +// +// } +// +// /** +// * 定位模式 被禁用 +// * @param provider +// */ +// @Override +// public void onProviderDisabled(String provider) { +// +// } +} diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/app/HttpLoggingInterceptor.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/HttpLoggingInterceptor.java new file mode 100644 index 0000000..fb9453d --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/HttpLoggingInterceptor.java @@ -0,0 +1,304 @@ +package com.ruansee.macall.testwebview.app; + +import android.net.Uri; + +import androidx.annotation.NonNull; + +import com.rs.macall.androidx.basemodel.utils.StringUtil; + +import java.io.EOFException; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import okhttp3.Connection; +import okhttp3.Headers; +import okhttp3.Interceptor; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okhttp3.ResponseBody; +import okhttp3.internal.http.HttpHeaders; +import okhttp3.internal.platform.Platform; +import okio.Buffer; +import okio.BufferedSource; + +import static okhttp3.internal.platform.Platform.INFO; + +public class HttpLoggingInterceptor implements Interceptor { + + private static final Charset UTF8 = Charset.forName("UTF-8"); + + private Map headers; + + public enum Level { + /** + * No logs. + */ + NONE, + /** + * Logs request and response lines. + * + *

Example: + *

{@code
+         * --> POST /greeting http/ic_btn_compare_mode.ic_btn_compare_mode (ic_tv_left_house-byte body)
+         *
+         * <-- 200 OK (22ms, 6-byte body)
+         * }
+ */ + BASIC, + /** + * Logs request and response lines and their respective headers. + * + *

Example: + *

{@code
+         * --> POST /greeting http/ic_btn_compare_mode.ic_btn_compare_mode
+         * Host: example.com
+         * Content-Type: plain/text
+         * Content-Length: ic_tv_left_house
+         * --> END POST
+         *
+         * <-- 200 OK (22ms)
+         * Content-Type: plain/text
+         * Content-Length: 6
+         * <-- END HTTP
+         * }
+ */ + HEADERS, + /** + * Logs request and response lines and their respective headers and bodies (if present). + * + *

Example: + *

{@code
+         * --> POST /greeting http/ic_btn_compare_mode.ic_btn_compare_mode
+         * Host: example.com
+         * Content-Type: plain/text
+         * Content-Length: ic_tv_left_house
+         *
+         * Hi?
+         * --> END POST
+         *
+         * <-- 200 OK (22ms)
+         * Content-Type: plain/text
+         * Content-Length: 6
+         *
+         * Hello!
+         * <-- END HTTP
+         * }
+ */ + BODY + } + + public interface Logger { + void log(String message); + + /** + * + */ + Logger DEFAULT = new Logger() { + @Override + public void log(String message) { + Platform.get().log(message, INFO, null); + } + }; + } + + public HttpLoggingInterceptor() { + this(Logger.DEFAULT); + } + + /** + * 设置请求Header + * + * @param headers header 集合 + */ + public HttpLoggingInterceptor(Map headers) { + this(Logger.DEFAULT); + this.headers = headers; + } + + public HttpLoggingInterceptor(Logger logger) { + this.logger = logger; + } + + private final Logger logger; + private volatile Level level = Level.BODY; + + private void log(String msg){ + if (RuanseeApp.isPrintLog){ + logger.log(msg); + } + } + + @NonNull + @Override + public Response intercept(@NonNull Chain chain) throws IOException { + // 在这里设置公共的Header + Request requestS = chain.request(); + Request.Builder requestBuilder = requestS.newBuilder(); +// if (StringUtil.hasContent(RuanseeApplication.getAppCache().getSystem_token())) { +// String heard = "Bearer " + RuanseeApplication.getAppCache().getSystem_token(); +// } +// if (StringUtil.isNullOrEmpty(RuanseeApplication.getAppCache().getUserInfo())){ +// String s = Base64.encodeBase64String(RuanseeApplication.getUserData().toJson().getBytes()); +// RuanseeApplication.getAppCache().setUserInfo(s); +// } +// requestBuilder.addHeader("userInfo", RuanseeApplication.getAppCache().getUserInfo()); +// String se = requestS.url().toString(); +// if (StringUtil.hasContent(se)) { +// if (!se.endsWith(".jpg") && !se.endsWith(".png")&&!se.contains("wzt")){ +// se = se.replace("http://" + RuanseeApplication.getAppCache().getIp() + ":8081/", RuanseeApplication.getAppCache().getBaseUrlPath()); +// } +// if (!se.endsWith(".jpg") && !se.endsWith(".png")&&!se.contains("wzt_api_out")){ +// se = se.replace("http://" + RuanseeApplication.getAppCache().getIp() + "/", RuanseeApplication.getAppCache().getBaseUrlPath()); +// } +// requestBuilder.url(se); +// } + //在这里设置公共的Header + Level level = this.level; + + Request request = requestBuilder.build(); + +// Request request = chain.request(); + if (level == Level.NONE) { + return chain.proceed(request); + } + + boolean logBody = level == Level.BODY; + boolean logHeaders = logBody || level == Level.HEADERS; + + RequestBody requestBody = request.body(); + boolean hasRequestBody = requestBody != null; + + Connection connection = chain.connection(); + String requestStartMessage = "--> " + + request.method() + + ' ' + request.url() + + (connection != null ? " " + connection.protocol() : ""); + if (!logHeaders && hasRequestBody) { + requestStartMessage += " (" + requestBody.contentLength() + "-byte body)"; + } + log(requestStartMessage); + + if (logHeaders) { + if (hasRequestBody) { + // Request body headers are only present when installed as a network interceptor. Force + // them to be included (when available) so there values are known. + if (requestBody.contentType() != null) { + log("Content-Type: " + requestBody.contentType()); + } + if (requestBody.contentLength() != -1) { + log("Content-Length: " + requestBody.contentLength()); + } + } + + Headers headers = request.headers(); + for (int i = 0, count = headers.size(); i < count; i++) { + log("Headers.name: " + headers.name(i) + ", Header.value: " + headers.value(i)); + } + + if (!logBody || !hasRequestBody) { + log("--> END " + request.method()); + } else if (bodyEncoded(request.headers())) { + log("--> END " + request.method() + " (encoded body omitted)"); + } else { + Buffer buffer = new Buffer(); + requestBody.writeTo(buffer); + + Charset charset = UTF8; + MediaType contentType = requestBody.contentType(); + if (contentType != null) { + charset = contentType.charset(UTF8); + } + + log(""); + if (isPlaintext(buffer)) { + log(buffer.readString(charset)); + log("--> END " + request.method() + + " (" + requestBody.contentLength() + "-byte body)"); + } else { + log("--> END " + request.method() + " (binary " + + requestBody.contentLength() + "-byte body omitted)"); + } + } + } + + long startNs = System.nanoTime(); + Response response; + try { + response = chain.proceed(request); + } catch (Exception e) { + log("<-- HTTP FAILED: " + e); + throw e; + } + long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs); + + ResponseBody responseBody = response.body(); + long contentLength = responseBody.contentLength(); + String bodySize = contentLength != -1 ? contentLength + "-byte" : "unknown-length"; + log("<-- response.code->" + + response.code() + + (response.message().isEmpty() ? "" : ' ' + response.message()) + + ' ' + response.request().url() + + " (" + tookMs + "ms" + (!logHeaders ? ", " + bodySize + " body" : "") + ')'); + + if (logHeaders) { + Headers headers = response.headers(); + for (int i = 0, count = headers.size(); i < count; i++) { + log("Headers: " + headers.name(i) + " = " + Uri.decode(headers.value(i))); + } + if (!logBody || !HttpHeaders.hasBody(response)) { + log("<-- END HTTP"); + } else if (bodyEncoded(response.headers())) { + log("<-- END HTTP (encoded body omitted)"); + } else { + BufferedSource source = responseBody.source(); + source.request(Long.MAX_VALUE); // Buffer the entire body. + Buffer buffer = source.buffer(); + Charset charset = UTF8; + MediaType contentType = responseBody.contentType(); + if (contentType != null) { + charset = contentType.charset(UTF8); + } + if (!isPlaintext(buffer)) { + log(""); + log("<-- END HTTP (binary " + buffer.size() + "-byte body omitted)"); + return response; + } + if (contentLength != 0) { + log(""); + log(buffer.clone().readString(charset)); + } + log("<-- END HTTP (" + buffer.size() + "-byte body)"); + } + } + return response; + } + + private static boolean isPlaintext(Buffer buffer) { + try { + Buffer prefix = new Buffer(); + long byteCount = buffer.size() < 64 ? buffer.size() : 64; + buffer.copyTo(prefix, 0, byteCount); + for (int i = 0; i < 16; i++) { + if (prefix.exhausted()) { + break; + } + int codePoint = prefix.readUtf8CodePoint(); + if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) { + return false; + } + } + return true; + } catch (EOFException e) { + return false; // Truncated UTF-8 sequence. + } + } + + private boolean bodyEncoded(Headers headers) { + String contentEncoding = headers.get("Content-Encoding"); + return contentEncoding != null && !contentEncoding.equalsIgnoreCase("identity"); + } +} diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/app/RuanseeApp.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/RuanseeApp.java new file mode 100644 index 0000000..828ce1c --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/RuanseeApp.java @@ -0,0 +1,30 @@ +package com.ruansee.macall.testwebview.app; + +import com.rs.macall.androidx.basemodel.base.BaseApplication; +import com.ruansee.macall.testwebview.utils.FileUtils; + +/** + * created by: Macall + * create time: 2023/12/7 9:19 + * copyright: @ruansee.com + * Describe: + */ +public class RuanseeApp extends BaseApplication { + public static boolean isPrintLog = false; + private static AppCacheData appCacheData; + { + CACHE_FILE_NAME = "H5WebViewTestTool"; + } + + @Override + protected void init() { + appCacheData = AppCacheData.getCacheData(); + FileUtils.initFilePath(getApplication()); + CrashHandler.getInstance().init(getApplication(),FileUtils.LOG_DIR); + + } + + public static AppCacheData getAppCacheData() { + return appCacheData; + } +} diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/app/WebActivityCallback.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/WebActivityCallback.java new file mode 100644 index 0000000..765f16c --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/WebActivityCallback.java @@ -0,0 +1,16 @@ +package com.ruansee.macall.testwebview.app; + +import com.rs.macall.androidx.basemodel.callback.BasePresenterCallback; + +/** + * created by: Macall + * create time: 2022/11/21 17:30 + * copyright: @ruansee.com + * Describe: + */ +public interface WebActivityCallback extends BasePresenterCallback { + + void onShowOperationSelectDialog( String[] split ,int whit); + + void onFinish(); +} diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/app/WebViewPresenter.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/WebViewPresenter.java new file mode 100644 index 0000000..46da155 --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/app/WebViewPresenter.java @@ -0,0 +1,513 @@ +package com.ruansee.macall.testwebview.app; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.DownloadManager; +import android.content.ClipData; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.net.http.SslError; +import android.os.Build; +import android.os.Environment; +import android.provider.MediaStore; +import android.view.LayoutInflater; +import android.view.View; +import android.webkit.JsResult; +import android.webkit.SslErrorHandler; +import android.webkit.URLUtil; +import android.webkit.ValueCallback; +import android.webkit.WebResourceError; +import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; +import android.webkit.WebView; +import android.widget.TextView; + +import com.just.agentweb.WebChromeClient; +import com.just.agentweb.WebViewClient; +import com.rs.macall.androidx.basemodel.base.BasePresenter; +import com.rs.macall.androidx.basemodel.callback.CustomClickListener; +import com.rs.macall.androidx.basemodel.utils.BitMapUtils; +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ruansee.macall.testwebview.R; +import com.ruansee.macall.testwebview.model.SelectFileOptions; +import com.ruansee.macall.testwebview.provider.DownloadUtil; +import com.ruansee.macall.testwebview.utils.FileUtils; +import com.ruansee.macall.testwebview.utils.UriUtils; + +import java.io.File; + +import top.zibin.luban.OnCompressListener; + +import static android.content.Context.DOWNLOAD_SERVICE; + +/** + * created by: Macall + * create time: 2022/11/21 17:26 + * copyright: @ruansee.com + * Describe: + */ +public class WebViewPresenter extends BasePresenter { + public File photoFile; + public final static int RESULT_CODE = 10000; + public final static int SELECT_IMG_CODE = 10001; + public final static int SELECT_FILE_CODE = 10002; + public SelectFileOptions selectFileOptions; + private String fileTypes; + private Dialog selectItems; + private boolean isLogin = false; + public String ywryName = "", ywryPhone = ""; + + public String intoUrl = "http://20.90.1.150:8888/"; +// public Map selectFileOptionsMap; + + public ValueCallback mFilePathCallback; + + public WebViewPresenter(Context context, WebActivityCallback callback) { + super(context, callback); +// selectFileOptionsMap = new HashMap<>(); + } + + public void onDestroy() { + + } + /** + * 相机拍照 + * + * @param activity 当前活动 + */ + private void skipPickPhoto(Activity activity) { + if (photoFile != null && photoFile.exists()) { + photoFile.delete(); + } + photoFile = new File(FileUtils.IMAGE_DIR, FileUtils.getPhotoName()); + Intent photoIntent = UriUtils.getPhotoIntent(activity, photoFile); + activity.startActivityForResult(photoIntent, RESULT_CODE); + } + + private void showSelectUploadDialog() { + if (selectFileOptions.onlyOneItemIsSelected()) { + if (selectFileOptions.isCamera()) { + callBack.onShowOperationSelectDialog(new String[]{"相机"}, 0); + return; + } + if (selectFileOptions.isDCIM()) { + callBack.onShowOperationSelectDialog(new String[]{"相册"}, 0); + return; + } + if (selectFileOptions.isFileSelection()) { + callBack.onShowOperationSelectDialog(new String[]{"文件选择"}, 0); + return; + } + } + int a = View.GONE, b = View.GONE, c = View.GONE; + StringBuilder builder = new StringBuilder(); + String sp = ""; + if (selectFileOptions.isCamera()) { + builder.append(sp); + builder.append("相机"); + a = View.VISIBLE; + sp = ","; + } + if (selectFileOptions.isDCIM()) { + builder.append(sp); + builder.append("相册"); + b = View.VISIBLE; + sp = ","; + } + if (selectFileOptions.isFileSelection()) { + builder.append(sp); + builder.append("文件选择"); + c = View.VISIBLE; + } + String str = builder.toString(); + if (StringUtil.isNullOrEmpty(str)) { + str = "相机,相册,文件选择"; + } + final String[] split = str.split(","); + if (selectItems == null) { + View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_select_items, null, false); + selectItems = new AlertDialog.Builder(getContext()) + .setView(view) + .setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + mFilePathCallback.onReceiveValue(null); + mFilePathCallback = null; + } + }) + .create(); + } + selectItems.show(); + TextView tv_title = selectItems.findViewById(R.id.tv_title); + tv_title.setText("选择操作方式"); + View tv_xj = selectItems.findViewById(R.id.tv_xj); + tv_xj.setVisibility(a); + View tv_xc = selectItems.findViewById(R.id.tv_xc); + tv_xc.setVisibility(b); + View tv_wjxz = selectItems.findViewById(R.id.tv_wjxz); + tv_wjxz.setVisibility(c); + tv_xj.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + selectItems.dismiss(); + callBack.onShowOperationSelectDialog(new String[]{"相机"}, 0); + } + }); + tv_xc.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + selectItems.dismiss(); + callBack.onShowOperationSelectDialog(new String[]{"相册"}, 0); + } + }); + tv_wjxz.setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + selectItems.dismiss(); + callBack.onShowOperationSelectDialog(new String[]{"文件选择"}, 0); + } + }); + } + + /** + * 显示选择文件弹框 + * + * @param whit 可操作的项 + * 1表示 只能相机拍照,将直接打开系统相机 + * 2表示 提供相机拍照、相册选取两个选项 + * 3表示 文件选取 + */ + public void onShowOperationSelectDialog(Activity activity, int whit, String[] split) { + String s = split[whit]; + switch (s) { + case "相机": + skipPickPhoto(activity); + break; + case "相册": + Intent intent = new Intent(Intent.ACTION_PICK, null); + intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, fileTypes); + intent.setType(fileTypes); + activity.startActivityForResult(intent, SELECT_IMG_CODE); + break; + case "文件选择": + intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.setType(fileTypes); + intent.addCategory(Intent.CATEGORY_OPENABLE); + activity.startActivityForResult(intent, SELECT_FILE_CODE); + break; + } + } + + /** + * 下载文件 + * + * @param url 文件URL + * @param fileName 文件名称 + * @param downloadListener 下载监听 + */ + public void downloadFile(String url, String fileName, DownloadUtil.OnDownloadListener downloadListener) { +// ApiModel.request(RetrofitService.getBaseInstance().downFile(url), new BaseRequestCallback() { +// @Override +// public void onRequestFailure(String msg) { +// // 下载失败 +// downloadListener.onDownloadFailed(msg); +// } +// +// @Override +// public void onRequestSuccess(ResponseBody result) { +// try { +// DownloadUtil.get().handDownFile(url,FileUtils.DOWNLOADS_DIR,result,fileName,downloadListener); +// } catch (IOException e) { +// e.printStackTrace(); +// // 下载失败 +// downloadListener.onDownloadFailed(e.getMessage()); +// } +// } +// }); + DownloadUtil.get().download(url, FileUtils.DOWNLOADS_DIR, fileName, downloadListener); + } + + public WebViewClient mWebViewClient = new WebViewClient() { + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + //do you work + LogUtils.w(String.format("onPageStarted : url=%s", url)); + if (url.startsWith(intoUrl) || url.startsWith("http://localhost")) { + if (isLogin) { + callBack.onFinish(); + } + isLogin = true; + } + } + + @Override + public void onLoadResource(WebView view, String url) { + super.onLoadResource(view, url); + } + + @Override + public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { + super.onReceivedError(view, request, error); + //net::ERR_NAME_NOT_RESOLVED -2 网页超时加载 执行这个回调 +// showLoadWebError("应用加载超时,请联系管理员排查系统。",ywryName,ywryPhone); + } + + @Override + public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) { + //内部系统 沒有用用户 +// errorResponse.getStatusCode() == 404; +// if(errorResponse.getStatusCode() == 404){ +// showLoadWebError("应用加载失败,用户没有权限,请联系管理添加权限。",ywryName,ywryPhone); +// }else { + super.onReceivedHttpError(view, request, errorResponse); +// } + } + + @Override + public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { + super.onReceivedSslError(view, handler, error); + } + + @Override + public void onPageFinished(WebView view, String url) { + view.getSettings().setBlockNetworkImage(false); + super.onPageFinished(view, url); + } + }; + + public WebChromeClient mWebChromeClient = new WebChromeClient() { + @Override + public void onProgressChanged(WebView view, int newProgress) { + //do you work + super.onProgressChanged(view, newProgress); + if (newProgress>=100){ + view.getSettings().setBlockNetworkImage(false); + } + LogUtils.w(TAG, String.format("onProgressChanged : newProgress=%s", newProgress)); + } + + @Override + public boolean onJsAlert(WebView view, String url, String message, JsResult result) { + //设置弹窗 + AlertDialog.Builder b = new AlertDialog.Builder(getContext()); + b.setTitle("Alert"); + b.setMessage(message); + b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + result.confirm(); + } + }); + b.setCancelable(true); + b.create().show(); + return true; + } + + @Override + public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) { + mFilePathCallback = filePathCallback; + if (fileChooserParams != null) { + if (fileChooserParams.getAcceptTypes() != null + && fileChooserParams.getAcceptTypes().length > 0) { + StringBuilder builder = new StringBuilder(); + String sp = ""; + for (int i = 0; i < fileChooserParams.getAcceptTypes().length; i++) { + builder.append(sp); + builder.append(fileChooserParams.getAcceptTypes()[0]); + sp = ";"; + } + fileTypes = builder.toString(); + } + } + if (StringUtil.isNullOrEmpty(fileTypes)) { + fileTypes = "*/*"; + } + if (selectFileOptions == null) { + selectFileOptions = new SelectFileOptions(false, true, true, true); + } + if (selectFileOptions.isSelfRealization()) { + return super.onShowFileChooser(webView, filePathCallback, fileChooserParams); + } + showSelectUploadDialog(); + return true; + } + }; + + + public void showLoadWebError(String titleStr, String msg, String lxryName, String lxryPhone) { + if (StringUtil.isNullOrEmpty(titleStr)){ + titleStr = "温馨提示"; + } + View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_h5_error, null, false); + Dialog insertTips = new AlertDialog.Builder(getContext()) + .setView(view) + .create(); + insertTips.show(); + TextView title = insertTips.findViewById(R.id.textView2); + title.setText(titleStr); + TextView tvMsg = insertTips.findViewById(R.id.tv_msg); + TextView tvYwry = insertTips.findViewById(R.id.tv_wery); + TextView tvPhone = insertTips.findViewById(R.id.tv_ywrydh); + tvMsg.setText(msg); + String name = "暂无"; + String lxdh ="暂无"; + if (StringUtil.isNullOrEmpty(lxryName)) { + if (StringUtil.hasContent(ywryName)) { + name =ywryName; + if (StringUtil.hasContent(ywryPhone)){ + lxdh = ywryPhone; + } + } + }else { + name = lxryName; + lxdh= StringUtil.isNullOrEmpty(lxryPhone)?"暂无":lxryPhone; + } + tvYwry.setText(name+":"); + tvPhone.setText(lxdh); + insertTips.findViewById(R.id.btn_determine).setOnClickListener(new CustomClickListener() { + @Override + public void onSingleClick(View v) { + insertTips.dismiss(); + callBack.onFinish(); + } + }); + } + + /** + * 处理选择相册和选择文件 + * + * @param requestCode + * @param resultCode + * @param intent + */ + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) { + Uri[] results = null; + if (resultCode == Activity.RESULT_OK) { + if (intent != null) { + String dataString = intent.getDataString(); + ClipData clipData = intent.getClipData(); + if (clipData != null) { + results = new Uri[clipData.getItemCount()]; + for (int i = 0; i < clipData.getItemCount(); i++) { + ClipData.Item item = clipData.getItemAt(i); + results[i] = item.getUri(); + } + } + if (dataString != null) + results = new Uri[]{Uri.parse(dataString)}; + } + mFilePathCallback.onReceiveValue(results); + mFilePathCallback = null; + } else { + mFilePathCallback.onReceiveValue(null); + mFilePathCallback = null; + } + } + + /** + * 压缩图片 + */ + public void ysBitmap() { + BitMapUtils.lubanCompress(getContext(), photoFile, FileUtils.IMAGE_DIR, new OnCompressListener() { + @Override + public void onStart() { + + } + + @Override + public void onSuccess(File file) { + if (!file.getAbsolutePath().equals(photoFile.getAbsolutePath())) { + photoFile.delete(); + photoFile = file; + } + Uri ph = UriUtils.getUri(getContext(), file); + Uri[] uris = new Uri[]{ph}; + mFilePathCallback.onReceiveValue(uris); + mFilePathCallback = null; + } + + @Override + public void onError(Throwable e) { + mFilePathCallback.onReceiveValue(null); + mFilePathCallback = null; + + } + }); + } + + /** + * 浏览器下载 + * + * @param url + */ + private void downloadByBrowser(String url) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.addCategory(Intent.CATEGORY_BROWSABLE); + intent.setData(Uri.parse(url)); + getContext().startActivity(intent); + } + + /** + * 系统下载服务下载 + * + * @param url + * @param contentDisposition + * @param mimeType + */ + public void downloadBySystem(String url, String contentDisposition, String mimeType) { + // 指定下载地址 + DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); + // 允许媒体扫描,根据下载的文件类型被加入相册、音乐等媒体库 + request.allowScanningByMediaScanner(); + // 设置通知的显示类型,下载进行时和完成后显示通知 + request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); + // 设置通知栏的标题,如果不设置,默认使用文件名 +// request.setTitle("This is title"); + // 设置通知栏的描述 +// request.setDescription("This is description"); + // 允许在计费流量下下载 + request.setAllowedOverMetered(false); + // 允许该记录在下载管理界面可见 + request.setVisibleInDownloadsUi(false); + // 允许漫游时下载 + request.setAllowedOverRoaming(true); + // 允许下载的网路类型 + request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI); + // 设置下载文件保存的路径和文件名 + String fileName = URLUtil.guessFileName(url, contentDisposition, mimeType); + LogUtils.d("fileName:{}", fileName); + request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); +// 另外可选一下方法,自定义下载路径 +// request.setDestinationUri() +// request.setDestinationInExternalFilesDir() + final DownloadManager downloadManager = (DownloadManager) getContext().getSystemService(DOWNLOAD_SERVICE); + // 添加一个下载任务 + long downloadId = downloadManager.enqueue(request); + LogUtils.d("downloadId:{}", downloadId + ""); + } + + + /** + * 打开GPS + */ +// private void openGPSSettings() { +// LocationManager alm = (LocationManager) context +// .getSystemService(Context.LOCATION_SERVICE); +// if (alm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) { +// Toast.makeText(context, "GPS模块正常", Toast.LENGTH_SHORT).show(); +//// baiDuMapManager.startLocation(); +// return; +// } else { +// Toast.makeText(context, "请开启GPS!", Toast.LENGTH_SHORT).show(); +// Intent intent = new Intent(Settings.ACTION_SECURITY_SETTINGS); +// startActivityForResult(intent, 0); // 此为设置完成后返回到获取界面 +// } +// } +} diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/model/SelectFileOptions.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/model/SelectFileOptions.java new file mode 100644 index 0000000..03da12a --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/model/SelectFileOptions.java @@ -0,0 +1,82 @@ +package com.ruansee.macall.testwebview.model; + +/** + * created by: Macall + * create time: 2022/11/21 18:16 + * copyright: @ruansee.com + * Describe: + */ +public class SelectFileOptions { + private boolean isCamera; + private boolean isDCIM; + private boolean isFileSelection; + private boolean selfRealization; + + public SelectFileOptions(boolean isCamera) { + this.isCamera = isCamera; + } + + public SelectFileOptions(boolean isDCIM, boolean isFileSelection) { + this.isDCIM = isDCIM; + this.isFileSelection = isFileSelection; + } + + public SelectFileOptions(boolean selfRealization, boolean isCamera, boolean isDCIM, boolean isFileSelection) { + this.selfRealization = selfRealization; + this.isCamera = isCamera; + this.isDCIM = isDCIM; + this.isFileSelection = isFileSelection; + } + public void configureOptions(boolean selfRealization,boolean isCamera, boolean isDCIM, boolean isFileSelection) { + this.selfRealization = selfRealization; + this.isCamera = isCamera; + this.isDCIM = isDCIM; + this.isFileSelection = isFileSelection; + } + + public boolean isCamera() { + return isCamera; + } + + public void setCamera(boolean camera) { + isCamera = camera; + } + + public boolean isDCIM() { + return isDCIM; + } + + public void setDCIM(boolean DCIM) { + isDCIM = DCIM; + } + + public boolean isFileSelection() { + return isFileSelection; + } + + public void setFileSelection(boolean fileSelection) { + isFileSelection = fileSelection; + } + + public boolean isSelfRealization() { + return selfRealization; + } + + public void setSelfRealization(boolean selfRealization) { + this.selfRealization = selfRealization; + } + + public boolean onlyOneItemIsSelected(){ + int count = 0; + if (isCamera){ + count++; + } + if (isDCIM){ + count++; + } + if (isFileSelection){ + count++; + } + return count==1; + } +} diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/provider/DownloadUtil.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/provider/DownloadUtil.java new file mode 100644 index 0000000..91447a5 --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/provider/DownloadUtil.java @@ -0,0 +1,286 @@ +package com.ruansee.macall.testwebview.provider; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Environment; + +import androidx.annotation.NonNull; + +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.ruansee.macall.testwebview.app.HttpLoggingInterceptor; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; + +/** + * created by: Macall + * create time: 2022/11/21 17:39 + * copyright: @ruansee.com + * Describe: + */ +public class DownloadUtil { + private static final String TAG = DownloadUtil.class.getName(); + private static DownloadUtil downloadUtil; + private final OkHttpClient okHttpClient; + + public static DownloadUtil get() { + if (downloadUtil == null) { + downloadUtil = new DownloadUtil(); + } + return downloadUtil; + } + + private DownloadUtil() { + okHttpClient = new OkHttpClient.Builder() + .connectTimeout(20, TimeUnit.SECONDS) + .writeTimeout(20, TimeUnit.SECONDS) + .readTimeout(20, TimeUnit.SECONDS) +// .addInterceptor(new HttpLoggingInterceptor()) + .build();; + + } + + /** + * 复制单个文件 + * + * @param oldPath$Name String 原文件路径+文件名 如:data/user/0/com.test/files/abc.txt + * @param newPath$Name String 复制后路径+文件名 如:data/user/0/com.test/cache/abc.txt + * @return true if and only if the file was copied; + * false otherwise + */ + public static boolean copyFile(String oldPath$Name, String newPath$Name) { + try { + File oldFile = new File(oldPath$Name); + if (!oldFile.exists()) { + LogUtils.e("--Method--", "copyFile: oldFile not exist."); + return false; + } else if (!oldFile.isFile()) { + LogUtils.e("--Method--", "copyFile: oldFile not file."); + return false; + } else if (!oldFile.canRead()) { + LogUtils.e("--Method--", "copyFile: oldFile cannot read."); + return false; + } + + /* 如果不需要打log,可以使用下面的语句 + if (!oldFile.exists() || !oldFile.isFile() || !oldFile.canRead()) { + return false; + } + */ + + FileInputStream fileInputStream = new FileInputStream(oldPath$Name); + FileOutputStream fileOutputStream = new FileOutputStream(newPath$Name); + byte[] buffer = new byte[1024]; + int byteRead; + while (-1 != (byteRead = fileInputStream.read(buffer))) { + fileOutputStream.write(buffer, 0, byteRead); + } + fileInputStream.close(); + fileOutputStream.flush(); + fileOutputStream.close(); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 通知相册更新 + * + * @param context + * @param newFile + */ + public void updateDCIM(Context context, File newFile) { + File cameraPath = new File(dcimPath, "Camera"); + File imgFile = new File(cameraPath, newFile.getAbsolutePath()); + if (imgFile.exists()) { + Uri uri = Uri.fromFile(imgFile); + Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + intent.setData(uri); + context.sendBroadcast(intent); + } + } + + + /** + * url 下载连接 + * saveDir 储存下载文件的SDCard目录 + * listener 下载监听 + */ + public void download(final String url, final String saveDir,String fileName, + final OnDownloadListener listener) { + Request request = new Request.Builder().url(url).build(); + okHttpClient.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + // 下载失败 + listener.onDownloadFailed(e.getMessage()); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + InputStream is = null; + byte[] buf = new byte[2048]; + int len = 0; + FileOutputStream fos = null; + // 储存下载文件的目录 + String savePath = isExistDir(saveDir); + try { + is = response.body().byteStream(); + long total = response.body().contentLength(); + String nameFromUrl =fileName; + if (StringUtil.isNullOrEmpty(nameFromUrl)){ + nameFromUrl = getNameFromUrl(url); + } + File file = new File(savePath, nameFromUrl); + fos = new FileOutputStream(file); + long sum = 0; + while ((len = is.read(buf)) != -1) { + fos.write(buf, 0, len); + sum += len; + int progress = (int) (sum * 1.0f / total * 100); + // 下载中 + listener.onDownloading(progress); + } + fos.flush(); + // 下载完成 + listener.onDownloadSuccess(file); + } catch (Exception e) { + listener.onDownloadFailed(e.getMessage()); + } finally { + try { + if (is != null) + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + if (fos != null) + fos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + }); + } + + public void handDownFile(String url, String saveDir, ResponseBody response, String fileName, OnDownloadListener listener) throws IOException { + InputStream is = null; + byte[] buf = new byte[2048]; + int len = 0; + FileOutputStream fos = null; + // 储存下载文件的目录 + String savePath = isExistDir(saveDir); + try { + is = response.byteStream(); + long total = response.contentLength(); + String nameFromUrl =fileName; + if (StringUtil.isNullOrEmpty(nameFromUrl)){ + nameFromUrl = getNameFromUrl(url); + } + File file = new File(savePath, nameFromUrl); + fos = new FileOutputStream(file); + long sum = 0; + while ((len = is.read(buf)) != -1) { + fos.write(buf, 0, len); + sum += len; + int progress = (int) (sum * 1.0f / total * 100); + // 下载中 + listener.onDownloading(progress); + } + fos.flush(); + // 下载完成 + listener.onDownloadSuccess(file); + } catch (Exception e) { + listener.onDownloadFailed(e.getMessage()); + } finally { + try { + if (is != null) + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + if (fos != null) + fos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * saveDir + * 判断下载目录是否存在 + */ + private static String isExistDir(String saveDir) throws IOException { + // 下载位置 + File downloadFile = new File(saveDir); + if (!downloadFile.mkdirs()) { + downloadFile.createNewFile(); + } + String savePath = downloadFile.getAbsolutePath(); + return savePath; + } + + //系统相册路径 + static String dcimPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath(); + + /** + * 创建文件夹 + */ + public static void createFiles(File oldFile) { + try { + File file = new File(isExistDir(dcimPath + "/xxx")); + String newPath = file.getPath() + "/" + oldFile.getName(); + LogUtils.d("TAG", "createFiles111: " + oldFile.getPath() + "--" + newPath); + if (copyFile(oldFile.getPath(), newPath)) { + LogUtils.d("TAG", "createFiles222: " + oldFile.getPath() + "--" + newPath); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + + /** + * url + * 从下载连接中解析出文件名 + */ + @NonNull + public static String getNameFromUrl(String url) { + return url.substring(url.lastIndexOf("/") + 1); + } + + public interface OnDownloadListener { + /** + * 下载成功 + */ + void onDownloadSuccess(File file); + + /** + * @param progress 下载进度 + */ + void onDownloading(int progress); + + /** + * 下载失败 + */ + void onDownloadFailed(String msg); + } +} diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/provider/MyFileProvider.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/provider/MyFileProvider.java new file mode 100644 index 0000000..38ee215 --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/provider/MyFileProvider.java @@ -0,0 +1,12 @@ +package com.ruansee.macall.testwebview.provider; + +import androidx.core.content.FileProvider; + +/** + * created by: Macall + * create time: 2023/12/7 11:40 + * copyright: @ruansee.com + * Describe: + */ +public class MyFileProvider extends FileProvider { +} diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/utils/FileUtils.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/utils/FileUtils.java new file mode 100644 index 0000000..a0e04a9 --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/utils/FileUtils.java @@ -0,0 +1,456 @@ +package com.ruansee.macall.testwebview.utils; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.graphics.Bitmap; +import android.graphics.Matrix; +import android.media.ExifInterface; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.util.Base64; + +import androidx.annotation.IntDef; +import androidx.core.content.FileProvider; + +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.rs.macall.androidx.basemodel.utils.StringUtil; +import com.rs.macall.androidx.basemodel.utils.ToastUtil; +import com.ruansee.macall.testwebview.R; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.text.DecimalFormat; +import java.util.List; + +/** + * created by: Macall + * create time: 2022/10/26 15:09 + * copyright: @ruansee.com + * Describe: + */ +public class FileUtils { + + private static String filePath; + + //文件路径 + public static String FILE_DIR = "file"; + //数据库文件路径 + public static String DB_DIR = "dateBase"; + //图片文件存储路径 + public static String IMAGE_DIR = "Image"; + //视频文件存储路径 + public static String VOID_DIR = "Void"; + //下载文件存储路径 + public static String DOWNLOADS_DIR = "downloads"; + //下载文件存储路径 + public static String LOG_DIR = "Log"; + + /** + * 初始化文件目录,Android10以下可以访问外部存储的任意位置,Android10(包括)以上只能访问指定目录。 + * 为适配Android 10 及以上,应用目录应存储在该目录下 + * + * @param context 上下文环境 + * @return 文件录 + */ + public static String initFilePath(Context context) { + if (StringUtil.isNullOrEmpty(filePath)) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + filePath = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath().replace("Documents", ""); + DOWNLOADS_DIR = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + File.separator; + IMAGE_DIR = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath() + File.separator; + VOID_DIR = context.getExternalFilesDir(Environment.DIRECTORY_DCIM).getAbsolutePath() + File.separator; + FILE_DIR = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + File.separator; + DB_DIR = FILE_DIR + "/dateBase/"; + LOG_DIR = filePath + "log/"; + } else { + // /storage/emulated/0/Android/data/com.spsj.data/files/Documents + filePath = Environment.getExternalStorageDirectory().getPath() + "/Android/data/com.ruansee.macall.testwebview/"; + DOWNLOADS_DIR = filePath + "Downloads/"; + IMAGE_DIR = filePath + "Pictures/"; + VOID_DIR = filePath + "DCIM/"; + FILE_DIR = filePath + "Documents/"; + DB_DIR = FILE_DIR + "/dateBase/"; + LOG_DIR = filePath + "log/"; + } + } + return filePath; + } + + public static String getPhotoName() { + return System.currentTimeMillis() + ".jpg"; + } + + + /** + * @param context + * @param attrsName + * @param filePath + * @return + */ + public static File copyAPK(Context context, String attrsName, String filePath) { + InputStream is = null; + try { + is = context.getAssets().open(attrsName); + File destFile = new File(filePath, attrsName); + if (destFile.exists()) { + destFile.delete(); + } +// if (!destFile.exists()) { + return copy(is, destFile.getAbsolutePath()); +// } +// return null; + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + public static File copy(InputStream is, String path) { + try { + File file = new File(path); + FileOutputStream fos = new FileOutputStream(file); + + byte[] buffer = new byte[1024]; + int len; + while ((len = is.read(buffer)) != -1) { + fos.write(buffer, 0, len); + } + fos.flush(); + fos.close(); + is.close(); + + return file; + } catch (Exception e) { + e.printStackTrace(); + return null; + + } + } + + /** + * 本地图片转 base64 字符 + * + * @param filePath 图标全路径 + * @return base64 字符 + */ + public static String fileToBase64(String filePath) { + if (StringUtil.isNullOrEmpty(filePath)) return ""; + File f = new File(filePath); + if (!f.exists()) return ""; + InputStream in = null; + byte[] data = null; + try { + in = new FileInputStream(f); + data = new byte[(int) f.length()]; + in.read(data); + in.close(); +// return Base64.encodeBase64String(data); +// return Base64.encodeBase64URLSafeString(data); + return Base64.encodeToString(data, Base64.DEFAULT); + } catch (IOException e) { + e.printStackTrace(); + return ""; + } + } + + public static void deleteFiles(File file) { + if (file == null || !file.exists()) return; + if (file.isDirectory()) { + File[] files = file.listFiles(); + for (int i = 0; i < files.length; i++) { + File file1 = files[i]; + deleteFiles(file1); + } + } else { + file.delete(); + } + } + + public static long calculateFileSize(File file) { + long totals = 0; + if (!file.exists()) return 0; + if (file.isDirectory()) { + File[] files = file.listFiles(); + if (files == null) return 0; + for (File fl : files) { + totals += calculateFileSize(fl); + } + } else { + totals += file.length(); + } + return totals; + } + + /** + * 文件重命名 + * + * @param dir 文件路径 + * @param sourcePath 原文件名 + * @param targetPath 修改后的文件名 + * @return 是否修改成功 + */ + public static boolean renameFile(String dir, String sourcePath, String targetPath) { + File toBeRenamed = new File(dir, sourcePath); + //检查要重命名的文件是否存在,是否是文件 + if (!toBeRenamed.exists() || toBeRenamed.isDirectory()) { + LogUtils.e("FileUtils", "待重命名文件不存在: " + sourcePath); + return false; + } + File newFile = new File(dir, targetPath); + //修改文件名 + return toBeRenamed.renameTo(newFile); + } + + /*打开app*/ + @TargetApi(Build.VERSION_CODES.DONUT) + private void doStartApplicationWithPackageName(Context context, String packagename) { + + // 通过包名获取此APP详细信息,包括Activities、services、versioncode、name等等 + PackageInfo packageinfo = null; + try { + packageinfo = context.getPackageManager().getPackageInfo(packagename, 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (packageinfo == null) { + return; + } + + // 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent + Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); + resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER); + resolveIntent.setPackage(packageinfo.packageName); + + // 通过getPackageManager()的queryIntentActivities方法遍历 + List resolveinfoList = context.getPackageManager() + .queryIntentActivities(resolveIntent, 0); + + ResolveInfo resolveinfo = resolveinfoList.iterator().next(); + if (resolveinfo != null) { + // packagename = 参数packname + String packageName = resolveinfo.activityInfo.packageName; + // 这个就是我们要找的该APP的LAUNCHER的Activity[组织形式:packagename.mainActivityname] + String className = resolveinfo.activityInfo.name; + // LAUNCHER Intent + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + + // 设置ComponentName参数1:packagename参数2:MainActivity路径 + ComponentName cn = new ComponentName(packageName, className); + + intent.setComponent(cn); + context.startActivity(intent); + } + } + + /** + * 文件大小单位 + */ + @IntDef(value = {FileSizeFormType.B, FileSizeFormType.K, FileSizeFormType.M, FileSizeFormType.T}) + @Retention(RetentionPolicy.SOURCE) + public @interface FileSizeFormType { + int B = 0; //bit + int K = 1; //KB + int M = 2; //MB + int T = 3; //TB + } + + /** + * 格式化文件大小 + * + * @param fileSize 文件大小单位 bit + * @param type 格式化单位{@link FileSizeFormType} + * @return 格式化后的大小 + */ + public static String formatFileSize(long fileSize, int type) { + DecimalFormat decimalFormat = new DecimalFormat("#.00"); + if (FileSizeFormType.K == type) { + return decimalFormat.format((double)fileSize / 1024 )+ "K"; + } else if (FileSizeFormType.M == type) { + return decimalFormat.format((double)fileSize / 1024 / 1024 )+ "M"; + } else if (FileSizeFormType.T == type) { + return decimalFormat.format((double)fileSize / 1024 / 1024 / 1024) + "T"; + } + return fileSize + "B"; + } + + + /** + * 根据路径打开文件 + * + * @param context 上下文 + * @param path 文件路径 + */ + public static void openFileByPath(Activity context, String path) { + if (context == null || path == null) return; + File file = new File(path); + if (!file.exists()) { + return; + } + Uri photoURI; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + //如果是7.0及以上的系统使用FileProvider的方式创建一个Uri + LogUtils.e("相机权限", "系统版本大于7.0"); +// String provider = context.getString(MResource.getIdByName(context.getApplication(), "string", "app_file_provider_authority")); + photoURI = FileProvider.getUriForFile(context, context.getString(R.string.fileProviderName), file); + } else { + //7.0以下使用这种方式创建一个Uri + photoURI = Uri.fromFile(file); + } + Intent intent = new Intent(); + //设置intent的Action属性 + intent.setAction(Intent.ACTION_VIEW); + //文件的类型 + intent.addCategory(Intent.CATEGORY_DEFAULT); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + String type = ""; + for (int i = 0; i < MATCH_ARRAY.length; i++) { + //判断文件的格式 + if (path.endsWith(MATCH_ARRAY[i][0])) { + type = MATCH_ARRAY[i][1]; + break; + } + } + try { + //设置intent的data和Type属性 + intent.setDataAndType(photoURI, type); + //跳转 + context.startActivity(intent); + } catch (Exception e) { //当系统没有携带文件打开软件,提示 + ToastUtil.centered(context, "无法打开该格式文件!"); + e.printStackTrace(); + file.delete(); + } + } + + //建立一个文件类型与文件后缀名的匹配表 + private static final String[][] MATCH_ARRAY = { + //{后缀名, 文件类型} + {".3gp", "video/3gpp"}, + {".apk", "application/vnd.android.package-archive"}, + {".asf", "video/x-ms-asf"}, + {".avi", "video/x-msvideo"}, + {".bin", "application/octet-stream"}, + {".bmp", "image/bmp"}, + {".c", "text/plain"}, + {".class", "application/octet-stream"}, + {".conf", "text/plain"}, + {".cpp", "text/plain"}, + {".doc", "application/msword"}, + {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}, + {".xls", "application/vnd.ms-excel"}, + {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}, + {".exe", "application/octet-stream"}, + {".gif", "image/gif"}, + {".gtar", "application/x-gtar"}, + {".gz", "application/x-gzip"}, + {".h", "text/plain"}, + {".htm", "text/html"}, + {".html", "text/html"}, + {".jar", "application/java-archive"}, + {".java", "text/plain"}, + {".jpeg", "image/jpeg"}, + {".jpg", "image/jpeg"}, + {".js", "application/x-javascript"}, + {".log", "text/plain"}, + {".m3u", "audio/x-mpegurl"}, + {".m4a", "audio/mp4a-latm"}, + {".m4b", "audio/mp4a-latm"}, + {".m4p", "audio/mp4a-latm"}, + {".m4u", "video/vnd.mpegurl"}, + {".m4v", "video/x-m4v"}, + {".mov", "video/quicktime"}, + {".mp2", "audio/x-mpeg"}, + {".mp3", "audio/x-mpeg"}, + {".mp4", "video/mp4"}, + {".mpc", "application/vnd.mpohun.certificate"}, + {".mpe", "video/mpeg"}, + {".mpeg", "video/mpeg"}, + {".mpg", "video/mpeg"}, + {".mpg4", "video/mp4"}, + {".mpga", "audio/mpeg"}, + {".msg", "application/vnd.ms-outlook"}, + {".ogg", "audio/ogg"}, + {".pdf", "application/pdf"}, + {".png", "image/png"}, + {".pps", "application/vnd.ms-powerpoint"}, + {".ppt", "application/vnd.ms-powerpoint"}, + {".prop", "text/plain"}, + {".rar", "application/x-rar-compressed"}, + {".rc", "text/plain"}, + {".rmvb", "audio/x-pn-realaudio"}, + {".rtf", "application/rtf"}, + {".sh", "text/plain"}, + {".tar", "application/x-tar"}, + {".tgz", "application/x-compressed"}, + {".txt", "text/plain"}, + {".wav", "audio/x-wav"}, + {".wma", "audio/x-ms-wma"}, + {".wmv", "audio/x-ms-wmv"}, + {".wps", "application/vnd.ms-works"}, + {".xml", "text/plain"}, + {".z", "application/x-compress"}, + {".zip", "application/zip"}, + {"", "*/*"} + }; + + /** + * 读取图片属性:旋转的角度 + * + * @param path 图片绝对路径 + * @return degree 旋转角度 + */ + public static int readPictureDegree(String path) { + int degree = 0; + try { + ExifInterface exifInterface = new ExifInterface(path); + int orientation = exifInterface.getAttributeInt( + ExifInterface.TAG_ORIENTATION, + ExifInterface.ORIENTATION_NORMAL); + switch (orientation) { + case ExifInterface.ORIENTATION_ROTATE_90: + degree = 90; + break; + case ExifInterface.ORIENTATION_ROTATE_180: + degree = 180; + break; + case ExifInterface.ORIENTATION_ROTATE_270: + degree = 270; + break; + } + } catch (IOException e) { + e.printStackTrace(); + } + return degree; + } + + /** + * 旋转图片 + * + * @param angle 旋转角度 + * @param bitmap 原图 + * @return bitmap 旋转后的图片 + */ + public static Bitmap rotateImage(int angle, Bitmap bitmap) { + // 图片旋转矩阵 + Matrix matrix = new Matrix(); + matrix.postRotate(angle); + // 得到旋转后的图片 + return Bitmap.createBitmap(bitmap, 0, 0, + bitmap.getWidth(), bitmap.getHeight(), matrix, true); + } + +} diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/utils/JiaMi.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/utils/JiaMi.java new file mode 100644 index 0000000..185e301 --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/utils/JiaMi.java @@ -0,0 +1,111 @@ +package com.ruansee.macall.testwebview.utils; + +import com.base.code.binary.Base64; + +import java.security.SecureRandom; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESKeySpec; + +/** + * created by: Macall + * create time: 2022/11/1 9:42 + * copyright: @ruansee.com + * Describe: + */ +public class JiaMi { + + /** + * 根据 key 加密 data , 并将加密后的数据进行Base64转码 + * @param data 待加密的数据 + * @param id id + * @param secret 秘钥 + * @return Base64字符 + */ + public static String desCrypto(byte[] data, String id,String secret) { + return desCrypto(data,String.format("%s:%s",id,secret)); + } + + /** + * 根据 key 加密 data , 并将加密后的数据进行Base64转码 + * @param data 待加密的数据 + * @param key 加密的KEY + * @return Base64字符 + */ + private static String desCrypto(byte[] data, String key) { + try{ + SecureRandom random = new SecureRandom(); + DESKeySpec desKey = new DESKeySpec(key.getBytes()); + //创建一个密匙工厂,然后用它把DESKeySpec转换成 + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + SecretKey securekey = keyFactory.generateSecret(desKey); + //Cipher对象实际完成加密操作 + Cipher cipher = Cipher.getInstance("DES"); + //用密匙初始化Cipher对象 + cipher.init(Cipher.ENCRYPT_MODE, securekey, random); + //现在,获取数据并加密 + //正式执行加密操作 + byte[] bytes = cipher.doFinal(data); + //进行Base64转码 + return Base64.encodeBase64String(bytes); + }catch(Throwable e){ + e.printStackTrace(); + } + return null; + } + + /** + * DES 解密 + * @param data 加密后的字符 + * @param key key + * @return 解密后的数据 + * @throws Exception 异常信息 + */ + private static byte[] decrypt(byte[] data, String key) throws Exception { + // DES算法要求有一个可信任的随机数源 + SecureRandom random = new SecureRandom(); + // 创建一个DESKeySpec对象 + DESKeySpec desKey = new DESKeySpec(key.getBytes()); + // 创建一个密匙工厂 + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + // 将DESKeySpec对象转换成SecretKey对象 + SecretKey securekey = keyFactory.generateSecret(desKey); + // Cipher对象实际完成解密操作 + Cipher cipher = Cipher.getInstance("DES"); + // 用密匙初始化Cipher对象 + cipher.init(Cipher.DECRYPT_MODE, securekey, random); + // 真正开始解密操作 + return cipher.doFinal(data); + } + + /** + * DES 解密 + * @param encryptData 加密后的字符 + * @param key key + * @return 解密后的数据 + * @throws Exception 异常信息 + */ + public static String decrypt(String encryptData, String key) throws Exception { + byte[] data = Base64.decodeBase64(encryptData); + byte[] decrypt = decrypt(data, key); + return new String(decrypt,"UTF-8"); + } + + /** + * DES 解密 + * @param encryptData 加密后的字符 + * @param id ID + * @param secret 秘钥 + * @return 解密后的数据 + * @throws Exception 异常信息 + */ + public static String decrypt(String encryptData, String id,String secret) throws Exception { + byte[] data = Base64.decodeBase64(encryptData); + byte[] decrypt = decrypt(data, String.format("%s:%s",id,secret)); + return new String(decrypt,"UTF-8"); + } + + +} diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/utils/LocationGPSManage.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/utils/LocationGPSManage.java new file mode 100644 index 0000000..5d5ac44 --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/utils/LocationGPSManage.java @@ -0,0 +1,379 @@ +package com.ruansee.macall.testwebview.utils; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Criteria; +import android.location.GnssStatus; +import android.location.GpsSatellite; +import android.location.GpsStatus; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.location.LocationProvider; +import android.os.Build; +import android.os.Bundle; + +import androidx.annotation.RequiresApi; +import androidx.core.app.ActivityCompat; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleObserver; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.OnLifecycleEvent; + +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.ruansee.macall.testwebview.app.GPSLocationListener; +import com.ruansee.macall.testwebview.app.RuanseeApp; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * created by: Macall + * create time: 2023/3/28 9:30 + * copyright: @ruansee.com + * Describe: 封装了GPS定位工具类 该类实现了 LifecycleObserver 用于监听 Activity 和 Fragment 的生命周期 + * 避免因退出页面而忘记关闭定位导致应用耗时增加的问题 + * TODO @see #onDestroy(LifecycleOwner) 使用时请在调用者(Activity 或 Fragment ) 调用如下代码 + * TODO { getLifecycle().addObserver(locationGPSManage) } + */ +public class LocationGPSManage implements LifecycleObserver { + private static LocationGPSManage locationGPSManage; + private LocationManager locationManager; + private boolean isLocation = false; + private MyLocationListener locationListener; + private MyGPSListener gpsListener; + private GnssStatus.Callback gnssStatusCallback; + + /** + * 记录上次搜索到的卫星数 + */ + private int startCount = -1; + + private List locationListenerList; + + /** + * 该方法不需要手动调用 + * 宿主执行了onDestroy时 会分发该事件 + * 使用时请在宿主(Activity 或 Fragment ) 中调用如下代码,调用后当 宿主执行什么周期方法 onDestroy 该方法自动被调用 + * { getLifecycle().addObserver(locationGPSManage) } + */ + @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) + void onDestroy(@NotNull LifecycleOwner owner) { + stopLocation(); + } + + private LocationGPSManage() { + } + + /** + * 添加一个位置监听 + * + * @param gpsLocationListener 监听接口实例对象 + */ + public void addGPSLocationListener(@NotNull GPSLocationListener gpsLocationListener) { + if (locationListenerList == null) { + locationListenerList = new ArrayList<>(); + } + if (locationListenerList.contains(gpsLocationListener)) return; + locationListenerList.add(gpsLocationListener); + } + + public static synchronized LocationGPSManage getInstance() { + if (locationGPSManage == null) { + synchronized (LocationGPSManage.class) { + if (locationGPSManage == null) { + locationGPSManage = new LocationGPSManage(); + } + } + } + return locationGPSManage; + } + + /** + * 开启定位 + * + * @param context 上下文环境 + * @param gpsLocationListener 位置监听,也可以调用{@link #addGPSLocationListener(GPSLocationListener)}方法传递 + * @throws RuntimeException 要先获取定位权限,否则将抛出异常 + */ + @SuppressLint("MissingPermission") + public void startGPSLocation(Context context, GPSLocationListener gpsLocationListener) throws RuntimeException { + boolean gpsPermission = isGPSPermission(context); + if (!gpsPermission) + throw new RuntimeException("Not ACCESS_FINE_LOCATION AND ACCESS_COARSE_LOCATION Permission"); + if (gpsLocationListener != null) { + addGPSLocationListener(gpsLocationListener); + } + //避免重复开启定位,该实例只允许开启一次定位 + if (isLocation) return; + LogUtils.w("启动GPS定位"); + locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + String bestProvider = locationManager.getBestProvider(getCriteria(), true); + String currentProvider = "gps"; + if ("gps".equals(bestProvider)) { + currentProvider = bestProvider; + } else { + //根据设置的Criteria对象,获取最符合此标准的provider对象 + LocationProvider provider = locationManager.getProvider(LocationManager.GPS_PROVIDER); + if (provider != null) { + currentProvider = provider.getName(); + } + } + LogUtils.w("获取的定位类型:" + currentProvider); + //根据当前provider对象获取最后一次位置信息 + Location currentLocation = locationManager.getLastKnownLocation(currentProvider); + if (locationListener == null) { + locationListener = new MyLocationListener(); + } + //如果位置信息不为NULL,则通知调用者最后一次位置 + if (currentLocation != null) { + locationListener.onLocationChanged(currentLocation); + } + //根据系统版本确定使用哪个卫星搜索监听 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (gnssStatusCallback == null) { + gnssStatusCallback = getGnssStatusCallback(); + } + locationManager.registerGnssStatusCallback(gnssStatusCallback); + } else { + if (gpsListener == null) { + gpsListener = new MyGPSListener(); + } + locationManager.addGpsStatusListener(gpsListener); + } + locationManager.requestLocationUpdates(currentProvider, 5 * 1000, 3, locationListener); + isLocation = true; + } + + /** + * 开启定位 + * + * @param context 上下文环境 + * @throws RuntimeException 要先获取定位权限,否则将抛出异常 + */ + @SuppressLint("MissingPermission") + public void startGPSLocation(Context context) throws RuntimeException { + startGPSLocation(context, null); + } + + private Criteria getCriteria() { + Criteria criteria = new Criteria(); +// 设置定位精确度 Criteria.ACCURACY_COARSE比较粗略,Criteria.ACCURACY_FINE则比较精细 + criteria.setAccuracy(Criteria.ACCURACY_COARSE); +// 设置是否要求速度 + criteria.setSpeedRequired(false); +// 设置是否允许运营商收费 + criteria.setCostAllowed(false); +// 设置是否需要方位信息 + criteria.setBearingRequired(true); +// 设置是否需要海拔信息 + criteria.setAltitudeRequired(true); +// 设置对电源的需求 + criteria.setPowerRequirement(Criteria.POWER_LOW); + return criteria; + } + + /** + * 停止定位,无论 {@link #startGPSLocation(Context)} 被执行多少此,该方法被执行时将停止位置监听,其他以监听位置的活动也无法继续获取位置监听 + * 需要重新执行 startGPSLocation 才能继续监听位置 + * TODO 该方法被调用后 所有的 调用 {@link #addGPSLocationListener(GPSLocationListener)}该方法添加的监听都会被清空,再次开启定位是需要重新传递监听回调 + */ + public void stopLocation() { + isLocation = false; + LogUtils.w("停止GPS定位"); + if (locationListenerList != null) { + for (GPSLocationListener l : locationListenerList) { + if (l != null) { + l.stopLocation(); + } + } + removeGPSLocationListenerAll(); + } + if (locationManager != null) { + if (gpsListener != null) { + locationManager.removeGpsStatusListener(gpsListener); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (gnssStatusCallback != null) { + locationManager.unregisterGnssStatusCallback(gnssStatusCallback); + } + } + if (locationListener != null) { + locationManager.removeUpdates(locationListener); + } + } + locationListener = null; + gpsListener = null; + } + + /** + * 注销某个位置监听 + * + * @param gpsLocationListener 监听实例对象 + */ + public void removeGPSLocationListener(GPSLocationListener gpsLocationListener) { + if (gpsLocationListener == null) return; + if (locationListenerList == null) return; + locationListenerList.remove(gpsLocationListener); + } + + /** + * 注销所有位置监听 + */ + public void removeGPSLocationListenerAll() { + if (locationListenerList == null) return; + locationListenerList.clear(); + } + + @SuppressLint("MissingPermission") + private class MyGPSListener implements GpsStatus.Listener { + //GPS状态发生变化时触发 + @Override + public void onGpsStatusChanged(int event) { + //获取当前状态 + GpsStatus gpsstatus = locationManager.getGpsStatus(null); + switch (event) { + //第一次定位时的事件 + case GpsStatus.GPS_EVENT_FIRST_FIX: + break; + //开始定位的事件 + case GpsStatus.GPS_EVENT_STARTED: + break; + //发送GPS卫星状态事件 + case GpsStatus.GPS_EVENT_SATELLITE_STATUS: + if (gpsstatus == null) return; + if (locationListenerList == null || locationListenerList.isEmpty()) return; + Iterable allSatellites = gpsstatus.getSatellites(); + if (allSatellites == null) return; + Iterator it = allSatellites.iterator(); + if (it == null) return; + int count = 0; + while (it.hasNext()) { + GpsSatellite next = it.next(); + if (next.getSnr() != 0) { + count++; + } + } +// LogUtils.v("搜索到:" + count + "颗卫星!"); + if (count == startCount) return; + for (GPSLocationListener l : locationListenerList) { + if (l != null) { + l.onScanSatellite(startCount, 0, 0); + } + } + break; + //停止定位事件 + case GpsStatus.GPS_EVENT_STOPPED: + LogUtils.w("Location", "GPS_EVENT_STOPPED"); + break; + } + } + } + + + @RequiresApi(api = Build.VERSION_CODES.N) + private GnssStatus.Callback getGnssStatusCallback() { + return new GnssStatus.Callback() { + @Override + public void onStarted() { + super.onStarted(); + } + + @Override + public void onSatelliteStatusChanged(GnssStatus status) { + if (locationListenerList == null || locationListenerList.isEmpty()) return; + int satelliteCount = status.getSatelliteCount(); + if (startCount != satelliteCount) { + startCount = satelliteCount; + //计算北东卫星数量 + int bdCount = 0; + //计算用于定位的卫星数量 + int locationCount = 0; + for (int i = 0; i < satelliteCount; i++) { + int constellationType = status.getConstellationType(i); + if (constellationType == GnssStatus.CONSTELLATION_BEIDOU) { + bdCount++; + } + if (status.usedInFix(i)) { + locationCount++; + } + } + for (GPSLocationListener l : locationListenerList) { + if (l != null) { + l.onScanSatellite(startCount, bdCount, locationCount); + } + } + if (RuanseeApp.isPrintLog) { + LogUtils.d("搜索卫星", String.format("搜索到:%s颗卫星,北斗卫星:%s颗,用于定位的卫星:%s颗", startCount, bdCount, locationCount)); + } + } + } + }; + } + + public boolean isGPSPermission(Context context) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && + ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + // TODO: Consider calling + // ActivityCompat#requestPermissions + return false; + } + return true; + } + + private class MyLocationListener implements LocationListener { + + /** + * 位置发生改变 + * + * @param location + */ + @Override + public void onLocationChanged(Location location) { + if (locationListenerList == null || locationListenerList.isEmpty()) return; + for (GPSLocationListener l : locationListenerList) { + if (l != null) { + l.onLocationChanged(location); + } + } + } + + /** + * 定位状态发生改变 + * + * @param provider + * @param status + * @param extras + */ + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + /** + * 启用 定位模式 + * + * @param provider + */ + @Override + public void onProviderEnabled(String provider) { + + } + + /** + * 定位模式 被禁用 + * + * @param provider + */ + @Override + public void onProviderDisabled(String provider) { + + } + } + +} diff --git a/testwebview/src/main/java/com/ruansee/macall/testwebview/utils/UriUtils.java b/testwebview/src/main/java/com/ruansee/macall/testwebview/utils/UriUtils.java new file mode 100644 index 0000000..201fb5d --- /dev/null +++ b/testwebview/src/main/java/com/ruansee/macall/testwebview/utils/UriUtils.java @@ -0,0 +1,237 @@ +package com.ruansee.macall.testwebview.utils; + +import android.annotation.SuppressLint; +import android.content.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; + +import androidx.core.content.FileProvider; + +import com.rs.macall.androidx.basemodel.utils.LogUtils; +import com.ruansee.macall.testwebview.R; + +import java.io.File; + +/** + * Created by Administrator on 2017/9/4. + * TODO 请注意 7.0以上版本需要配置 FileProvider 并将 配置的 authorities 值添加到 string.xml 中,key 值为 ”fileProviderName“ + */ +public class UriUtils { + + public static Intent getPhotoIntent(Context context, File file) { + Intent intent = new Intent(); + // 指定开启系统相机的Action + intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); + Uri photoURI; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + //如果是7.0及以上的系统使用FileProvider的方式创建一个Uri + LogUtils.e("相机权限", "系统版本大于7.0"); + //TODO 请注意 7.0以上版本需要配置 FileProvider + photoURI = FileProvider.getUriForFile(context, context.getString(R.string.fileProviderName), file); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + } else { + //7.0以下使用这种方式创建一个Uri + photoURI = Uri.fromFile(file); + } + intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); + return intent; + } + + /** + * 获取Uri + * @param context + * @param file + * @return + */ + public static Uri getUri(Context context, File file) { + if (context == null || file == null) return null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + //如果是7.0及以上的系统使用FileProvider的方式创建一个Uri + LogUtils.e("相机权限", "系统版本大于7.0"); + return FileProvider.getUriForFile(context, context.getString(R.string.fileProviderName), file); + } + //7.0以下使用这种方式创建一个Uri + return Uri.fromFile(file); + } + + /** + * 根据Uri获取图片的绝对路径 + * + * @param context 上下文对象 + * @param uri 图片的Uri + * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null + */ + public static String getRealPathFromUri(Context context, Uri uri) { + int sdkVersion = Build.VERSION.SDK_INT; + if (sdkVersion >= 19) { // api >= 19 + return getRealPathFromUriAboveApi19(context, uri); + } else { // api < 19 + return getRealPathFromUriBelowAPI19(context, uri); + } + } + + /** + * 适配api19以下(不包括api19),根据uri获取图片的绝对路径 + * + * @param context 上下文对象 + * @param uri 图片的Uri + * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null + */ + private static String getRealPathFromUriBelowAPI19(Context context, Uri uri) { + return getDataColumn(context, uri, null, null); + } + + /** + * 适配api19及以上,根据uri获取图片的绝对路径 + * + * @param context 上下文对象 + * @param uri 图片的Uri + * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null + */ + @SuppressLint("NewApi") + private static String getRealPathFromUriAboveApi19(Context context, Uri uri) { + String filePath = null; + if (DocumentsContract.isDocumentUri(context, uri)) { + // 如果是document类型的 uri, 则通过document id来进行处理 + String documentId = DocumentsContract.getDocumentId(uri); + if (isMediaDocument(uri)) { // MediaProvider + // 使用':'分割 + String id = documentId.split(":")[1]; + + String selection = MediaStore.Images.Media._ID + "=?"; + String[] selectionArgs = {id}; + filePath = getDataColumn(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs); + } else if (isDownloadsDocument(uri)) { // DownloadsProvider + Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(documentId)); + filePath = getDataColumn(context, contentUri, null, null); + } + } else if ("content".equalsIgnoreCase(uri.getScheme())) { + // 如果是 content 类型的 Uri + filePath = getDataColumn(context, uri, null, null); + } else if ("file".equals(uri.getScheme())) { + // 如果是 file 类型的 Uri,直接获取图片对应的路径 + filePath = uri.getPath(); + } + return filePath; + } + + /** + * 获取数据库表中的 _data 列,即返回Uri对应的文件路径 + * + * @return + */ + private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { + String path = null; + + String[] projection = new String[]{MediaStore.Images.Media.DATA}; + Cursor cursor = null; + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); + if (cursor != null && cursor.moveToFirst()) { + int columnIndex = cursor.getColumnIndexOrThrow(projection[0]); + path = cursor.getString(columnIndex); + } + } catch (Exception e) { + e.printStackTrace(); + if (cursor != null) { + cursor.close(); + } + } + return path; + } + + /** + * @param uri the Uri to check + * @return Whether the Uri authority is MediaProvider + */ + private static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + + /** + * @param uri the Uri to check + * @return Whether the Uri authority is DownloadsProvider + */ + private static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + public static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + public static String getPath(final Context context, final Uri uri) { + + final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + + // DocumentProvider + if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { + // ExternalStorageProvider + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + if ("primary".equalsIgnoreCase(type)) { + return Environment.getExternalStorageDirectory() + "/" + split[1]; + } else { + return "/storage/" + split[0] + "/" + split[1]; + } + + // TODO handle non-primary volumes + } + // DownloadsProvider + else if (isDownloadsDocument(uri)) { + + final String id = DocumentsContract.getDocumentId(uri); + try { + final Uri contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + return getDataColumn(context, contentUri, null, null); + } catch (NumberFormatException e) { + return ""; + } + + } + // MediaProvider + else if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri = null; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + + final String selection = "_id=?"; + final String[] selectionArgs = new String[]{split[1]}; + + return getDataColumn(context, contentUri, selection, selectionArgs); + } + } + // MediaStore (and general) + else if ("content".equalsIgnoreCase(uri.getScheme())) { + return getDataColumn(context, uri, null, null); + } + // File + else if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + + return ""; + } + + +} diff --git a/testwebview/src/main/res/drawable-v24/ic_launcher_foreground.xml b/testwebview/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/testwebview/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/testwebview/src/main/res/drawable-xxxhdpi/gradient_main.xml b/testwebview/src/main/res/drawable-xxxhdpi/gradient_main.xml new file mode 100644 index 0000000..4c300e7 --- /dev/null +++ b/testwebview/src/main/res/drawable-xxxhdpi/gradient_main.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/testwebview/src/main/res/drawable-xxxhdpi/ic_back.png b/testwebview/src/main/res/drawable-xxxhdpi/ic_back.png new file mode 100644 index 0000000..bd550d5 Binary files /dev/null and b/testwebview/src/main/res/drawable-xxxhdpi/ic_back.png differ diff --git a/testwebview/src/main/res/drawable-xxxhdpi/ic_back_b.png b/testwebview/src/main/res/drawable-xxxhdpi/ic_back_b.png new file mode 100644 index 0000000..9c3c2ed Binary files /dev/null and b/testwebview/src/main/res/drawable-xxxhdpi/ic_back_b.png differ diff --git a/testwebview/src/main/res/drawable-xxxhdpi/icon_h5.png b/testwebview/src/main/res/drawable-xxxhdpi/icon_h5.png new file mode 100644 index 0000000..f18a6e1 Binary files /dev/null and b/testwebview/src/main/res/drawable-xxxhdpi/icon_h5.png differ diff --git a/testwebview/src/main/res/drawable-xxxhdpi/icon_login.png b/testwebview/src/main/res/drawable-xxxhdpi/icon_login.png new file mode 100644 index 0000000..4bb802c Binary files /dev/null and b/testwebview/src/main/res/drawable-xxxhdpi/icon_login.png differ diff --git a/testwebview/src/main/res/drawable-xxxhdpi/icon_login2.png b/testwebview/src/main/res/drawable-xxxhdpi/icon_login2.png new file mode 100644 index 0000000..672a178 Binary files /dev/null and b/testwebview/src/main/res/drawable-xxxhdpi/icon_login2.png differ diff --git a/testwebview/src/main/res/drawable-xxxhdpi/icon_main_top.png b/testwebview/src/main/res/drawable-xxxhdpi/icon_main_top.png new file mode 100644 index 0000000..1469274 Binary files /dev/null and b/testwebview/src/main/res/drawable-xxxhdpi/icon_main_top.png differ diff --git a/testwebview/src/main/res/drawable-xxxhdpi/icon_msg_ld_back.png b/testwebview/src/main/res/drawable-xxxhdpi/icon_msg_ld_back.png new file mode 100644 index 0000000..1c2461a Binary files /dev/null and b/testwebview/src/main/res/drawable-xxxhdpi/icon_msg_ld_back.png differ diff --git a/testwebview/src/main/res/drawable-xxxhdpi/icon_msg_ld_white.png b/testwebview/src/main/res/drawable-xxxhdpi/icon_msg_ld_white.png new file mode 100644 index 0000000..7400a1a Binary files /dev/null and b/testwebview/src/main/res/drawable-xxxhdpi/icon_msg_ld_white.png differ diff --git a/testwebview/src/main/res/drawable-xxxhdpi/icon_over.png b/testwebview/src/main/res/drawable-xxxhdpi/icon_over.png new file mode 100644 index 0000000..d1f9747 Binary files /dev/null and b/testwebview/src/main/res/drawable-xxxhdpi/icon_over.png differ diff --git a/testwebview/src/main/res/drawable-xxxhdpi/icon_over_back.png b/testwebview/src/main/res/drawable-xxxhdpi/icon_over_back.png new file mode 100644 index 0000000..98649fa Binary files /dev/null and b/testwebview/src/main/res/drawable-xxxhdpi/icon_over_back.png differ diff --git a/testwebview/src/main/res/drawable-xxxhdpi/icon_refresh.png b/testwebview/src/main/res/drawable-xxxhdpi/icon_refresh.png new file mode 100644 index 0000000..9e7643f Binary files /dev/null and b/testwebview/src/main/res/drawable-xxxhdpi/icon_refresh.png differ diff --git a/testwebview/src/main/res/drawable-xxxhdpi/icon_refresh_grad.png b/testwebview/src/main/res/drawable-xxxhdpi/icon_refresh_grad.png new file mode 100644 index 0000000..ec19ea6 Binary files /dev/null and b/testwebview/src/main/res/drawable-xxxhdpi/icon_refresh_grad.png differ diff --git a/testwebview/src/main/res/drawable-xxxhdpi/icon_setting.png b/testwebview/src/main/res/drawable-xxxhdpi/icon_setting.png new file mode 100644 index 0000000..2da1cf3 Binary files /dev/null and b/testwebview/src/main/res/drawable-xxxhdpi/icon_setting.png differ diff --git a/testwebview/src/main/res/drawable-xxxhdpi/icon_title_bg.png b/testwebview/src/main/res/drawable-xxxhdpi/icon_title_bg.png new file mode 100644 index 0000000..55015b4 Binary files /dev/null and b/testwebview/src/main/res/drawable-xxxhdpi/icon_title_bg.png differ diff --git a/testwebview/src/main/res/drawable/card_white.xml b/testwebview/src/main/res/drawable/card_white.xml new file mode 100644 index 0000000..6f68789 --- /dev/null +++ b/testwebview/src/main/res/drawable/card_white.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/testwebview/src/main/res/drawable/ic_launcher_background.xml b/testwebview/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/testwebview/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testwebview/src/main/res/layout/activity_main.xml b/testwebview/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..bc56be5 --- /dev/null +++ b/testwebview/src/main/res/layout/activity_main.xml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testwebview/src/main/res/layout/activity_open_app.xml b/testwebview/src/main/res/layout/activity_open_app.xml new file mode 100644 index 0000000..ee726fd --- /dev/null +++ b/testwebview/src/main/res/layout/activity_open_app.xml @@ -0,0 +1,138 @@ + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + +