From 0187e23edea15df41bb3f1cdba876a9ce1138c08 Mon Sep 17 00:00:00 2001 From: lianlilong <409813353@qq.com> Date: Fri, 5 Apr 2024 21:53:51 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=AC=E4=B8=80=E6=AC=A1=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 16 + app/.gitignore | 2 + app/build.gradle | 75 ++ app/proguard-rules.pro | 21 + app/src/main/AndroidManifest.xml | 62 ++ .../policedatasystem/MyApplication.java | 26 + .../activity/KeyPersonDetailActivity.java | 173 ++++ .../PoliceEmergencyDetailActivity.java | 71 ++ .../activity/RotatedTextView.java | 43 + .../adapter/KeyPersonAdapter.java | 35 + .../adapter/PoliceEmergencyAdapter.java | 23 + .../fragment/ApplyFragment.java | 99 ++ .../fragment/DataFragment.java | 415 ++++++++ .../fragment/MineFragment.java | 91 ++ .../policedatasystem/http/CustomCallBack.java | 40 + .../policedatasystem/http/RequestClient.java | 593 ++++++++++++ .../GetKeyPersonDetailParams.java | 45 + .../requestparams/GetKeyPersonListParams.java | 89 ++ .../GetKeyPersonMessageCountParams.java | 80 ++ .../GetOrgKeyPersonListParams.java | 81 ++ .../GetPoliceEmergencyDetailParams.java | 45 + .../GetPoliceEmergencyListParams.java | 81 ++ .../http/requestparams/RequestParams.java | 156 +++ .../http/requestparams/ResponseParams.java | 96 ++ .../policedatasystem/indexActivity.java | 132 +++ .../policedatasystem/model/DataCount.java | 49 + .../policedatasystem/model/KeyPerson.java | 86 ++ .../model/KeyPersonDetail.java | 289 ++++++ .../model/PoliceEmergency.java | 56 ++ .../model/PoliceEmergencyDetail.java | 268 ++++++ .../policedatasystem/model/ResourceList.java | 42 + .../model/UserCredential.java | 174 ++++ .../policedatasystem/util/Constants.java | 63 ++ .../policedatasystem/util/ThirdAppInfo.java | 65 ++ .../util/UaCredentialApi.java | 305 ++++++ .../police/policedatasystem/util/UiUtils.java | 78 ++ .../viewmodel/DataViewModel.java | 360 +++++++ .../viewmodel/IndexViewModel.java | 13 + .../policedatasystem/widget/WaterMarkBg.java | 88 ++ .../widget/WaterMarkInfo.java | 208 ++++ .../widget/WaterMarkManager.java | 188 ++++ .../widget/WaterMarkView.java | 334 +++++++ app/src/main/res/color/bottom_nav_colors.xml | 5 + app/src/main/res/drawable/all_10_ccc_bg.xml | 6 + app/src/main/res/drawable/all_2_4b8e01_bg.xml | 6 + app/src/main/res/drawable/all_2_de7900_bg.xml | 6 + .../main/res/drawable/all_2_selected_bg.xml | 6 + app/src/main/res/drawable/all_3_ccc_bg.xml | 6 + app/src/main/res/drawable/all_7_fff_bg.xml | 6 + .../main/res/drawable/all_7_line_ccc_bg.xml | 6 + app/src/main/res/drawable/all_7_main_bg.xml | 6 + app/src/main/res/drawable/back.png | Bin 0 -> 688 bytes app/src/main/res/drawable/baojing.png | Bin 0 -> 604 bytes app/src/main/res/drawable/bg.png | Bin 0 -> 459347 bytes app/src/main/res/drawable/huizhang.png | Bin 0 -> 1684 bytes app/src/main/res/drawable/huizhang_icon.png | Bin 0 -> 1705 bytes .../res/drawable/ic_launcher_background.xml | 170 ++++ .../res/drawable/ic_launcher_foreground.xml | 30 + app/src/main/res/drawable/icon_14.png | Bin 0 -> 598 bytes app/src/main/res/drawable/jaintou.png | Bin 0 -> 344 bytes app/src/main/res/drawable/jinghui.png | Bin 0 -> 23065 bytes app/src/main/res/drawable/laba.png | Bin 0 -> 1184 bytes app/src/main/res/drawable/loading.gif | Bin 0 -> 6286 bytes app/src/main/res/drawable/mine.png | Bin 0 -> 695 bytes app/src/main/res/drawable/mine_icon.png | Bin 0 -> 1834 bytes app/src/main/res/drawable/mine_normal.png | Bin 0 -> 1834 bytes app/src/main/res/drawable/photo.png | Bin 0 -> 23229 bytes .../main/res/drawable/right_7_052eba_bg.xml | 7 + app/src/main/res/drawable/search.png | Bin 0 -> 1039 bytes app/src/main/res/drawable/top_10_f7_bg.xml | 7 + app/src/main/res/drawable/wenjian_9.png | Bin 0 -> 422 bytes app/src/main/res/drawable/wenjianjia.png | Bin 0 -> 865 bytes app/src/main/res/drawable/wenjianjia_icon.png | Bin 0 -> 863 bytes app/src/main/res/layout/activity_index.xml | 34 + .../res/layout/activity_key_person_detail.xml | 896 ++++++++++++++++++ app/src/main/res/layout/activity_main.xml | 9 + .../activity_police_emergency_detail.xml | 581 ++++++++++++ .../res/layout/bottom_navigation_view.xml | 79 ++ app/src/main/res/layout/dropdown_layout.xml | 31 + app/src/main/res/layout/dropdown_layout2.xml | 41 + app/src/main/res/layout/dropdown_layout3.xml | 52 + app/src/main/res/layout/dropdown_layout4.xml | 76 ++ app/src/main/res/layout/dropdown_layout5.xml | 66 ++ app/src/main/res/layout/fragment_apply.xml | 110 +++ app/src/main/res/layout/fragment_data.xml | 359 +++++++ app/src/main/res/layout/fragment_first.xml | 35 + app/src/main/res/layout/fragment_mine.xml | 140 +++ app/src/main/res/layout/fragment_second.xml | 35 + .../main/res/layout/item_apply_fragment_1.xml | 148 +++ app/src/main/res/layout/item_key_person.xml | 131 +++ .../main/res/layout/item_police_emergency.xml | 142 +++ app/src/main/res/layout/view_water_mark.xml | 4 + app/src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 1404 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 2898 bytes app/src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 982 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 1772 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 1900 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 3918 bytes app/src/main/res/mipmap-xxhdpi/bg.png | Bin 0 -> 459347 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 2884 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 5914 bytes app/src/main/res/mipmap-xxhdpi/icon_apply.png | Bin 0 -> 2286 bytes .../res/mipmap-xxhdpi/icon_apply_normal.png | Bin 0 -> 2286 bytes .../res/mipmap-xxhdpi/icon_apply_selected.png | Bin 0 -> 2348 bytes app/src/main/res/mipmap-xxhdpi/icon_data.png | Bin 0 -> 2256 bytes .../res/mipmap-xxhdpi/icon_data_normal.png | Bin 0 -> 2256 bytes .../res/mipmap-xxhdpi/icon_data_selected.png | Bin 0 -> 2329 bytes app/src/main/res/mipmap-xxhdpi/icon_mine.png | Bin 0 -> 1923 bytes .../res/mipmap-xxhdpi/icon_mine_normal.png | Bin 0 -> 2509 bytes .../res/mipmap-xxhdpi/icon_mine_selected.png | Bin 0 -> 2561 bytes app/src/main/res/mipmap-xxhdpi/icon_query.png | Bin 0 -> 1954 bytes app/src/main/res/mipmap-xxhdpi/jinghui.png | Bin 0 -> 23065 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 3844 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 7778 bytes app/src/main/res/values/attrs.xml | 19 + app/src/main/res/values/colors.xml | 15 + app/src/main/res/values/dimens.xml | 6 + app/src/main/res/values/strings.xml | 55 ++ app/src/main/res/values/themes.xml | 19 + app/src/main/res/xml/backup_rules.xml | 13 + .../main/res/xml/data_extraction_rules.xml | 19 + .../main/res/xml/network_security_config.xml | 8 + build.gradle | 5 + gradle.properties | 24 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 185 ++++ gradlew.bat | 89 ++ readme.md | 445 +++++++++ settings.gradle | 32 + 130 files changed, 9432 insertions(+) create mode 100644 .gitignore create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/police/policedatasystem/MyApplication.java create mode 100644 app/src/main/java/com/police/policedatasystem/activity/KeyPersonDetailActivity.java create mode 100644 app/src/main/java/com/police/policedatasystem/activity/PoliceEmergencyDetailActivity.java create mode 100644 app/src/main/java/com/police/policedatasystem/activity/RotatedTextView.java create mode 100644 app/src/main/java/com/police/policedatasystem/adapter/KeyPersonAdapter.java create mode 100644 app/src/main/java/com/police/policedatasystem/adapter/PoliceEmergencyAdapter.java create mode 100644 app/src/main/java/com/police/policedatasystem/fragment/ApplyFragment.java create mode 100644 app/src/main/java/com/police/policedatasystem/fragment/DataFragment.java create mode 100644 app/src/main/java/com/police/policedatasystem/fragment/MineFragment.java create mode 100644 app/src/main/java/com/police/policedatasystem/http/CustomCallBack.java create mode 100644 app/src/main/java/com/police/policedatasystem/http/RequestClient.java create mode 100644 app/src/main/java/com/police/policedatasystem/http/requestparams/GetKeyPersonDetailParams.java create mode 100644 app/src/main/java/com/police/policedatasystem/http/requestparams/GetKeyPersonListParams.java create mode 100644 app/src/main/java/com/police/policedatasystem/http/requestparams/GetKeyPersonMessageCountParams.java create mode 100644 app/src/main/java/com/police/policedatasystem/http/requestparams/GetOrgKeyPersonListParams.java create mode 100644 app/src/main/java/com/police/policedatasystem/http/requestparams/GetPoliceEmergencyDetailParams.java create mode 100644 app/src/main/java/com/police/policedatasystem/http/requestparams/GetPoliceEmergencyListParams.java create mode 100644 app/src/main/java/com/police/policedatasystem/http/requestparams/RequestParams.java create mode 100644 app/src/main/java/com/police/policedatasystem/http/requestparams/ResponseParams.java create mode 100644 app/src/main/java/com/police/policedatasystem/indexActivity.java create mode 100644 app/src/main/java/com/police/policedatasystem/model/DataCount.java create mode 100644 app/src/main/java/com/police/policedatasystem/model/KeyPerson.java create mode 100644 app/src/main/java/com/police/policedatasystem/model/KeyPersonDetail.java create mode 100644 app/src/main/java/com/police/policedatasystem/model/PoliceEmergency.java create mode 100644 app/src/main/java/com/police/policedatasystem/model/PoliceEmergencyDetail.java create mode 100644 app/src/main/java/com/police/policedatasystem/model/ResourceList.java create mode 100644 app/src/main/java/com/police/policedatasystem/model/UserCredential.java create mode 100644 app/src/main/java/com/police/policedatasystem/util/Constants.java create mode 100644 app/src/main/java/com/police/policedatasystem/util/ThirdAppInfo.java create mode 100644 app/src/main/java/com/police/policedatasystem/util/UaCredentialApi.java create mode 100644 app/src/main/java/com/police/policedatasystem/util/UiUtils.java create mode 100644 app/src/main/java/com/police/policedatasystem/viewmodel/DataViewModel.java create mode 100644 app/src/main/java/com/police/policedatasystem/viewmodel/IndexViewModel.java create mode 100644 app/src/main/java/com/police/policedatasystem/widget/WaterMarkBg.java create mode 100644 app/src/main/java/com/police/policedatasystem/widget/WaterMarkInfo.java create mode 100644 app/src/main/java/com/police/policedatasystem/widget/WaterMarkManager.java create mode 100644 app/src/main/java/com/police/policedatasystem/widget/WaterMarkView.java create mode 100644 app/src/main/res/color/bottom_nav_colors.xml create mode 100644 app/src/main/res/drawable/all_10_ccc_bg.xml create mode 100644 app/src/main/res/drawable/all_2_4b8e01_bg.xml create mode 100644 app/src/main/res/drawable/all_2_de7900_bg.xml create mode 100644 app/src/main/res/drawable/all_2_selected_bg.xml create mode 100644 app/src/main/res/drawable/all_3_ccc_bg.xml create mode 100644 app/src/main/res/drawable/all_7_fff_bg.xml create mode 100644 app/src/main/res/drawable/all_7_line_ccc_bg.xml create mode 100644 app/src/main/res/drawable/all_7_main_bg.xml create mode 100644 app/src/main/res/drawable/back.png create mode 100644 app/src/main/res/drawable/baojing.png create mode 100644 app/src/main/res/drawable/bg.png create mode 100644 app/src/main/res/drawable/huizhang.png create mode 100644 app/src/main/res/drawable/huizhang_icon.png create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/drawable/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/icon_14.png create mode 100644 app/src/main/res/drawable/jaintou.png create mode 100644 app/src/main/res/drawable/jinghui.png create mode 100644 app/src/main/res/drawable/laba.png create mode 100644 app/src/main/res/drawable/loading.gif create mode 100644 app/src/main/res/drawable/mine.png create mode 100644 app/src/main/res/drawable/mine_icon.png create mode 100644 app/src/main/res/drawable/mine_normal.png create mode 100644 app/src/main/res/drawable/photo.png create mode 100644 app/src/main/res/drawable/right_7_052eba_bg.xml create mode 100644 app/src/main/res/drawable/search.png create mode 100644 app/src/main/res/drawable/top_10_f7_bg.xml create mode 100644 app/src/main/res/drawable/wenjian_9.png create mode 100644 app/src/main/res/drawable/wenjianjia.png create mode 100644 app/src/main/res/drawable/wenjianjia_icon.png create mode 100644 app/src/main/res/layout/activity_index.xml create mode 100644 app/src/main/res/layout/activity_key_person_detail.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/activity_police_emergency_detail.xml create mode 100644 app/src/main/res/layout/bottom_navigation_view.xml create mode 100644 app/src/main/res/layout/dropdown_layout.xml create mode 100644 app/src/main/res/layout/dropdown_layout2.xml create mode 100644 app/src/main/res/layout/dropdown_layout3.xml create mode 100644 app/src/main/res/layout/dropdown_layout4.xml create mode 100644 app/src/main/res/layout/dropdown_layout5.xml create mode 100644 app/src/main/res/layout/fragment_apply.xml create mode 100644 app/src/main/res/layout/fragment_data.xml create mode 100644 app/src/main/res/layout/fragment_first.xml create mode 100644 app/src/main/res/layout/fragment_mine.xml create mode 100644 app/src/main/res/layout/fragment_second.xml create mode 100644 app/src/main/res/layout/item_apply_fragment_1.xml create mode 100644 app/src/main/res/layout/item_key_person.xml create mode 100644 app/src/main/res/layout/item_police_emergency.xml create mode 100644 app/src/main/res/layout/view_water_mark.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/bg.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/icon_apply.png create mode 100644 app/src/main/res/mipmap-xxhdpi/icon_apply_normal.png create mode 100644 app/src/main/res/mipmap-xxhdpi/icon_apply_selected.png create mode 100644 app/src/main/res/mipmap-xxhdpi/icon_data.png create mode 100644 app/src/main/res/mipmap-xxhdpi/icon_data_normal.png create mode 100644 app/src/main/res/mipmap-xxhdpi/icon_data_selected.png create mode 100644 app/src/main/res/mipmap-xxhdpi/icon_mine.png create mode 100644 app/src/main/res/mipmap-xxhdpi/icon_mine_normal.png create mode 100644 app/src/main/res/mipmap-xxhdpi/icon_mine_selected.png create mode 100644 app/src/main/res/mipmap-xxhdpi/icon_query.png create mode 100644 app/src/main/res/mipmap-xxhdpi/jinghui.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/values/attrs.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/themes.xml create mode 100644 app/src/main/res/xml/backup_rules.xml create mode 100644 app/src/main/res/xml/data_extraction_rules.xml create mode 100644 app/src/main/res/xml/network_security_config.xml create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 readme.md create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d4c3a57 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties +/.idea/ diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..dc5ca96 --- /dev/null +++ b/app/.gitignore @@ -0,0 +1,2 @@ +/build +/release/ diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..3a70d2d --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,75 @@ +plugins { + id 'com.android.application' + id 'org.jetbrains.kotlin.android' +} + +android { + namespace 'com.police.policedatasystem' + compileSdk 33 + viewBinding { + enabled = true + } + defaultConfig { + applicationId "com.police.policedatasystem" + minSdk 24 + targetSdk 33 + versionCode 10019 + versionName "1.0.19" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { + useSupportLibrary true + } + } + + applicationVariants.configureEach { variant -> + variant.outputs.configureEach { + outputFileName = "app_release${variant.versionName}.apk" + } + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } + buildFeatures { + compose true + viewBinding true + } + composeOptions { + kotlinCompilerExtensionVersion '1.4.3' + } + packaging { + resources { + excludes += '/META-INF/{AL2.0,LGPL2.1}' + } + } +} + +dependencies { + implementation 'androidx.appcompat:appcompat:1.0.0' + implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0' + implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4' + implementation 'androidx.recyclerview:recyclerview:1.3.2' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' +// implementation 'com.squareup.retrofit2:adapter-okhttp3:2.9.0' // OkHttp适配器 + implementation 'com.scwang.smart:refresh-layout-kernel:2.0.3' + implementation 'com.scwang.smart:refresh-footer-classics:2.0.3'//经典刷新脚部局 + implementation 'com.scwang.smart:refresh-header-classics:2.0.3'//经典刷新头布局 +// implementation 'io.reactivex:rxjava:1.3.8' +// implementation 'io.reactivex:rxandroid:1.2.1' + implementation 'com.squareup.retrofit2:retrofit:2.9.0' // 根据需要选择合适的版本 + implementation 'com.squareup.retrofit2:converter-gson:2.9.0' // 如果你使用 Gson 进行 JSON 转换 + implementation 'com.squareup.okhttp3:logging-interceptor:4.7.2' + implementation 'com.squareup.okhttp3:okhttp:4.8.1' // OkHttp库 + implementation 'com.github.bumptech.glide:glide:4.16.0' + implementation 'com.google.android.material:material:1.8.0' +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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 \ 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..f4e4383 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/MyApplication.java b/app/src/main/java/com/police/policedatasystem/MyApplication.java new file mode 100644 index 0000000..9c10173 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/MyApplication.java @@ -0,0 +1,26 @@ +package com.police.policedatasystem; + +import android.app.Application; +import android.os.Handler; + + +public class MyApplication extends Application { + private static MyApplication instance; + private static Handler handler; + + + public static MyApplication getInstance() { + return instance; + } + + @Override + public void onCreate() { + super.onCreate(); + handler = new Handler(); + instance = this; + } + + public static Handler getHandler() { + return handler; + } +} diff --git a/app/src/main/java/com/police/policedatasystem/activity/KeyPersonDetailActivity.java b/app/src/main/java/com/police/policedatasystem/activity/KeyPersonDetailActivity.java new file mode 100644 index 0000000..118fc85 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/activity/KeyPersonDetailActivity.java @@ -0,0 +1,173 @@ +package com.police.policedatasystem.activity; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.google.gson.Gson; +import com.police.policedatasystem.databinding.ActivityKeyPersonDetailBinding; +import com.police.policedatasystem.model.KeyPersonDetail; +import com.police.policedatasystem.util.Constants; +import com.police.policedatasystem.util.UiUtils; + +public class KeyPersonDetailActivity extends Activity { + private ActivityKeyPersonDetailBinding binding; + private KeyPersonDetail keyPersonDetail; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityKeyPersonDetailBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + initListener(); + String sfzh = getIntent().getStringExtra("sfzh"); + keyPersonDetail = new Gson().fromJson(sfzh, KeyPersonDetail.class); + binding.wm.setTextSize(50); + binding.wm.setText(Constants.SFZH); + showData(); + } + + private void showData() { + /** + * 基本信息数据显示 + */ + binding.tvName.setText(keyPersonDetail.getXm()); + binding.tvSex.setText(keyPersonDetail.getXb()); + if (UiUtils.isNotEmpty(keyPersonDetail.getHypo())) { + binding.tvMarital.setVisibility(View.VISIBLE); + binding.tvMarital.setText("已婚"); + } + if (UiUtils.isNotEmpty(keyPersonDetail.getBq())) { + binding.tvBq.setText(keyPersonDetail.getBq()); + binding.tvBq.setVisibility(View.VISIBLE); + } + setText(binding.tvNation, keyPersonDetail.getMz()); + setText(binding.detailSfzh, keyPersonDetail.getGmsfhm()); + if (UiUtils.isNotEmpty(keyPersonDetail.getJzdhhm())) { + String[] split = keyPersonDetail.getJzdhhm().split(","); + binding.detailSjh.setText(split[0]);//手机号 + } + setText(binding.detailHj, keyPersonDetail.getJg()); + setText(binding.detailGldz, keyPersonDetail.getHjdz()); + setText(binding.detailFwcs, keyPersonDetail.getFwcs()); + if (UiUtils.isNotEmpty(keyPersonDetail.getDjchphm())) { + binding.detailClxx.setText(keyPersonDetail.getDjchphm());//车辆信息 + } + + /** + * 位置信息数据显示 + */ + + if (UiUtils.isNotEmpty(keyPersonDetail.getSjgj())) { + setText(binding.tvBodyLastLocationPhone, sCountSp(keyPersonDetail.getSjgj()));//手机基站位置信息 + setText(binding.tvBodyLastLocationPhoneTime, UiUtils.formatTime(keyPersonDetail.getSjgj().split(",")[1]));//手机最后定位时间 + } + if (UiUtils.isNotEmpty(keyPersonDetail.getClzhwz())) { + setText(binding.tvBodyLastLocation, sCountSp(keyPersonDetail.getClzhwz()));//车辆最后位置 + setText(binding.tvBodyLastTime, UiUtils.formatTime(keyPersonDetail.getClzhwz().split(",")[1]));//车辆最后定位时间 + } + if (UiUtils.isNotEmpty(keyPersonDetail.getHcdp())) { + setText(binding.tvBodyTrainInfo, keyPersonDetail.getHcdp().split(",")[3] + "," + keyPersonDetail.getHcdp().split(",")[4] + " - " + keyPersonDetail.getHcdp().split(",")[5]);//火车订票 + setText(binding.tvBodyTrainTime, UiUtils.formatTime(keyPersonDetail.getHcdp().split(",")[2]));//火车发车时间 + } + if (UiUtils.isNotEmpty(keyPersonDetail.getKcdp())) { + setText(binding.tvBodyBusInfo, keyPersonDetail.getKcdp().split(",")[7] + "," + keyPersonDetail.getKcdp().split(",")[2] + " - " + keyPersonDetail.getKcdp().split(",")[6]);//客车订票、、 tCount(keyPersonDetail.getKcdp()) + setText(binding.tvBodyBusTime, UiUtils.formatTime(keyPersonDetail.getKcdp().split(",")[4]));//客车发车时间 + } + if (UiUtils.isNotEmpty(keyPersonDetail.getFjdp())) { + setText(binding.tvBodyFlyInfo, keyPersonDetail.getFjdp().split(",")[4] + "," + keyPersonDetail.getFjdp().split(",")[6] + " - " + keyPersonDetail.getFjdp().split(",")[9]);//飞机订票 + setText(binding.tvBodyFlyTime, UiUtils.formatTime(keyPersonDetail.getFjdp().split(",")[7]));//飞机起飞时间 + } + if (UiUtils.isNotEmpty(keyPersonDetail.getZjzs())) { + setText(binding.tvBodyRestInfo, tCount(keyPersonDetail.getZjzs()));//最近住宿 + } + if (keyPersonDetail.getZp() != null) { + loadBase64Image(binding.ivPhoto, keyPersonDetail.getZp()); + } + + /** + * 列控数据信息显示 + */ + if (keyPersonDetail.getLsajcs() > 0) { + setText(binding.tvBodyCtrlLevel, keyPersonDetail.getZdryLkxxList().get(0).getGklb());//管理级别 + setText(binding.tvBodyCtrlType, keyPersonDetail.getZdryLkxxList().get(0).getQtlb());//列管级别 + setText(binding.tvBodyCtrlTag, keyPersonDetail.getZdryLkxxList().get(0).getLkjz());//列控警种 + setText(binding.tvBodyCtrlTime, UiUtils.formatTime(keyPersonDetail.getZdryLkxxList().get(0).getLksj()));//列控时间 + setText(binding.tvBodyCtrlCause, keyPersonDetail.getZdryLkxxList().get(0).getLkyy());//列控原因 + setText(binding.tvBodyCtrlPerson, keyPersonDetail.getZdryLkxxList().get(0).getZrdw());//责任单位 + setText(binding.tvBodyCtrlPolice, keyPersonDetail.getZdryLkxxList().get(0).getZrmj());//责任民警 + } + + } + + public void loadBase64Image(ImageView imageView, String base64Str) { + Glide.with(imageView.getContext()) + .asBitmap() + .load(base64Str) + .into(imageView); + } + + /** + * 第3次索引 + * + * @param str + * @return + */ + private String tCount(String str) { + String c = ","; + int firstIndex = str.indexOf(c); + int secondIndex = str.indexOf(c, firstIndex + 1); + int thirdIndex = str.indexOf(c, secondIndex + 1); + return str.substring(thirdIndex + 1, str.length()); + } + + /** + * 第2个索引 + * + * @param str + * @return + */ + private String sCount(String str) { + String c = ","; + int firstIndex = str.indexOf(c); + int secondIndex = str.indexOf(c, firstIndex + 1); + return str.substring(secondIndex + 1, str.length()); + } + + /** + * 第2个索引 + * + * @param str + * @return + */ + private String sCountSp(String str) { + try { + return str.split(",")[3]; + } catch (Exception e) { + return ""; + } + } + + private void initListener() { + binding.ivBack.setOnClickListener(view -> finish()); + } + + public static void startAction(Context context, String num) { + Intent intent = new Intent(context, KeyPersonDetailActivity.class); + intent.putExtra("sfzh", num); + context.startActivity(intent); + } + + private void setText(TextView view, String str) { + if (UiUtils.isNotEmpty(str)) { + view.setText(str); + } else { + view.setText("无"); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/activity/PoliceEmergencyDetailActivity.java b/app/src/main/java/com/police/policedatasystem/activity/PoliceEmergencyDetailActivity.java new file mode 100644 index 0000000..1b753c6 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/activity/PoliceEmergencyDetailActivity.java @@ -0,0 +1,71 @@ +package com.police.policedatasystem.activity; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.google.gson.Gson; +import com.police.policedatasystem.MyApplication; +import com.police.policedatasystem.databinding.ActivityPoliceEmergencyDetailBinding; +import com.police.policedatasystem.model.PoliceEmergencyDetail; +import com.police.policedatasystem.util.Constants; +import com.police.policedatasystem.util.UiUtils; + +/** + * 警情详情页面 + */ +public class PoliceEmergencyDetailActivity extends Activity { + + private ActivityPoliceEmergencyDetailBinding binding; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityPoliceEmergencyDetailBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + binding.wm.setTextSize(50); + binding.wm.setText(Constants.SFZH); + binding.ivBack.setOnClickListener(view -> finish()); + PoliceEmergencyDetail detail = new Gson().fromJson(getIntent().getStringExtra("param"), PoliceEmergencyDetail.class); + if (UiUtils.isNotEmpty(detail.getZp())) { + Glide.with(MyApplication.getInstance()).asBitmap().load(detail.getZp()).into(binding.ivZp); + } + setText(binding.tvJcjbh, detail.getJcjbh());//报警编号 + setText(binding.tvBjjyqk, detail.getBjjyqk());//报警内容 + setText(binding.tvBjrlxdh, detail.getBjrlxdh());//报警电话 + setText(binding.tvJjsj, UiUtils.formatTime(detail.getJjsj()));//报警时间 + setText(binding.tvAsjfsdddzmc, detail.getAsjfsdddzmc());//报警位置 + setText(binding.tvCjdwgajgjgdm, detail.getCjdwgajgjgdm());//出警单位 + setText(binding.tvCjrxm, detail.getCjrxm());//出警民警 + setText(binding.tvBq, detail.getBq());//标签 + setText(binding.tvJg, detail.getJg());//籍贯 + setText(binding.tvXm, detail.getXm());//姓名 + setText(binding.tvXb, detail.getXb());//性别 + setText(binding.tvMz, detail.getMz());//民族 + setText(binding.tvHyzk, detail.getHyzk());//婚姻状况 + setText(binding.tvSfzh, detail.getBjrzjhm());//身份证号 + setText(binding.tvNl, detail.getNl());//年龄 + setText(binding.tvFwcs, detail.getFwcs());//服务场所 + setText(binding.tvLsbjcs, detail.getLsbjcs());//历史报警次数 + setText(binding.tvJqlb, detail.getJqlb());//警情类别 + setText(binding.tvCllb, detail.getCllx());//处理类型 + setText(binding.tvCljg, detail.getCljg());//处理结果 + } + + public static void startAction(Context context, String num) { + Intent intent = new Intent(context, PoliceEmergencyDetailActivity.class); + intent.putExtra("param", num); + context.startActivity(intent); + } + + private void setText(TextView view, String str) { + if (UiUtils.isNotEmpty(str)) { + view.setText(str); + } else { + view.setText("无"); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/activity/RotatedTextView.java b/app/src/main/java/com/police/policedatasystem/activity/RotatedTextView.java new file mode 100644 index 0000000..fa22b86 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/activity/RotatedTextView.java @@ -0,0 +1,43 @@ +package com.police.policedatasystem.activity; + +import android.content.Context; +import android.graphics.Canvas; +import android.util.AttributeSet; +import android.widget.TextView; + +public class RotatedTextView extends TextView { + + private float rotationAngle=300; // 旋转角度 + + public RotatedTextView(Context context) { + super(context); + } + + public RotatedTextView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public RotatedTextView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + // 设置旋转角度 + public void setRotationAngle(float angle) { + this.rotationAngle = angle; + invalidate(); // 重新绘制 + } + + @Override + protected void onDraw(Canvas canvas) { + int width = getWidth(); + int height = getHeight(); + int centerX = width / 10; + int centerY = height / 3; + + canvas.save(); // 保存当前画布状态 + canvas.translate(centerX, centerY); // 将坐标原点移动到中心点 + canvas.rotate(rotationAngle, centerX, centerY); // 旋转画布 + super.onDraw(canvas); // 绘制原始的TextView + canvas.restore(); // 恢复画布状态 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/adapter/KeyPersonAdapter.java b/app/src/main/java/com/police/policedatasystem/adapter/KeyPersonAdapter.java new file mode 100644 index 0000000..1541678 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/adapter/KeyPersonAdapter.java @@ -0,0 +1,35 @@ +package com.police.policedatasystem.adapter; + +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.police.policedatasystem.MyApplication; +import com.police.policedatasystem.R; +import com.police.policedatasystem.model.KeyPerson; +import com.police.policedatasystem.util.UiUtils; + +public class KeyPersonAdapter extends BaseQuickAdapter { + + public KeyPersonAdapter() { + super(R.layout.item_key_person); // 指定列表项的布局 + } + + @Override + protected void convert(BaseViewHolder helper, KeyPerson item) { + helper.setText(R.id.item_name, item.getXm()); + helper.setText(R.id.item_sfzh, item.getSfzh()); + helper.setText(R.id.item_gklb, item.getGklb()); + helper.setText(R.id.item_qtlb, item.getQtlb()); + helper.setText(R.id.item_zrmj, item.getZrmj()); + if (UiUtils.isNotEmpty(item.getZp())) { + Glide.with(MyApplication.getInstance()) + .asBitmap() + .load(item.getZp()) + .into((ImageView) helper.getView(R.id.iv_photo)); + } else { + helper.setImageResource(R.id.iv_photo, R.drawable.photo); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/adapter/PoliceEmergencyAdapter.java b/app/src/main/java/com/police/policedatasystem/adapter/PoliceEmergencyAdapter.java new file mode 100644 index 0000000..261b4ff --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/adapter/PoliceEmergencyAdapter.java @@ -0,0 +1,23 @@ +package com.police.policedatasystem.adapter; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.police.policedatasystem.R; +import com.police.policedatasystem.model.PoliceEmergency; +import com.police.policedatasystem.util.UiUtils; + +public class PoliceEmergencyAdapter extends BaseQuickAdapter { + + public PoliceEmergencyAdapter() { + super(R.layout.item_police_emergency); // 指定列表项的布局 + } + + @Override + protected void convert(BaseViewHolder helper, PoliceEmergency item) { + helper.setText(R.id.tv_police_num_title, "警情编号:"+item.getJcjbh());//警情编号 + helper.setText(R.id.item_content, item.getBjjyqk());//报警内容 + helper.setText(R.id.tv_police_tel, item.getBjrlxdh());//报警电话 + helper.setText(R.id.tv_police_time, UiUtils.formatTime(item.getJjsj()));//报警时间 + helper.setText(R.id.tv_police_loc, item.getAsjfsdddzmc());//报警地址 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/fragment/ApplyFragment.java b/app/src/main/java/com/police/policedatasystem/fragment/ApplyFragment.java new file mode 100644 index 0000000..a97ea94 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/fragment/ApplyFragment.java @@ -0,0 +1,99 @@ +package com.police.policedatasystem.fragment; + +import android.content.Context; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.PopupWindow; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import com.police.policedatasystem.R; +import com.police.policedatasystem.databinding.FragmentApplyBinding; + +public class ApplyFragment extends Fragment { + private FragmentApplyBinding binding; + private PopupWindow popupWindow; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + binding = FragmentApplyBinding.inflate(inflater); + initView(); + return binding.getRoot(); + } + + private void initView() { + setPopupWindow(); + binding.typeGroup.setOnClickListener(view -> { + popupWindow.setWidth(binding.typeGroup.getWidth()); + popupWindow.showAsDropDown(binding.typeGroup); + }); + } + + private void setPopupWindow() { + // 初始化 PopupWindow + popupWindow = new PopupWindow(getContext()); + // 加载自定义布局 + LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View contentView = inflater.inflate(R.layout.dropdown_layout4, null); + // 设置 PopupWindow 的宽高 + popupWindow.setWidth(LinearLayout.LayoutParams.MATCH_PARENT); + popupWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.all_7_fff_bg)); + popupWindow.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT); + // 设置 PopupWindow 的背景 +// popupWindow.setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); + // 设置 PopupWindow 显示的位置(相对于按钮) + popupWindow.showAtLocation(binding.typeGroup, Gravity.NO_GRAVITY, 0, 0); + // 为每个菜单项设置点击事件 + TextView textView1 = contentView.findViewById(R.id.textView1); // 假设这是菜单项1的ID + TextView textView2 = contentView.findViewById(R.id.textView2); // 假设这是菜单项2的ID + TextView textView3 = contentView.findViewById(R.id.textView3); // 假设这是菜单项2的ID + TextView textView4 = contentView.findViewById(R.id.textView4); // 假设这是菜单项2的ID + TextView textView5 = contentView.findViewById(R.id.textView5); // 假设这是菜单项2的ID + TextView textView6 = contentView.findViewById(R.id.textView6); // 假设这是菜单项2的ID + textView1.setOnClickListener(v -> { + // 处理菜单项 1 的点击事件 + binding.tvApplySearchTitle.setText("处置警情"); + popupWindow.dismiss(); // 关闭 PopupWindow + }); + textView2.setOnClickListener(v -> { + // 处理菜单项 2 的点击事件 + binding.tvApplySearchTitle.setText("处置案情"); + popupWindow.dismiss(); // 关闭 PopupWindow + }); + textView3.setOnClickListener(v -> { + // 处理菜单项 2 的点击事件 + binding.tvApplySearchTitle.setText("管控重点人"); + popupWindow.dismiss(); // 关闭 PopupWindow + }); + textView4.setOnClickListener(v -> { + // 处理菜单项 2 的点击事件 + binding.tvApplySearchTitle.setText("追踪逃犯"); + popupWindow.dismiss(); // 关闭 PopupWindow + }); + textView5.setOnClickListener(v -> { + // 处理菜单项 2 的点击事件 + binding.tvApplySearchTitle.setText("核查线索"); + popupWindow.dismiss(); // 关闭 PopupWindow + }); + textView6.setOnClickListener(v -> { + // 处理菜单项 2 的点击事件 + binding.tvApplySearchTitle.setText("核验信息"); + popupWindow.dismiss(); // 关闭 PopupWindow + }); + // 将自定义布局设置为 PopupWindow 的内容视图 + popupWindow.setContentView(contentView); + // 设置 PopupWindow 的焦点 + popupWindow.setFocusable(true); + popupWindow.setOutsideTouchable(true); // 设置点击 PopupWindow 外部区域使其消失 + } + +} diff --git a/app/src/main/java/com/police/policedatasystem/fragment/DataFragment.java b/app/src/main/java/com/police/policedatasystem/fragment/DataFragment.java new file mode 100644 index 0000000..183105c --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/fragment/DataFragment.java @@ -0,0 +1,415 @@ +package com.police.policedatasystem.fragment; + +import android.app.Activity; +import android.content.Context; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.PopupWindow; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.police.policedatasystem.R; +import com.police.policedatasystem.adapter.KeyPersonAdapter; +import com.police.policedatasystem.adapter.PoliceEmergencyAdapter; +import com.police.policedatasystem.databinding.FragmentDataBinding; +import com.police.policedatasystem.indexActivity; +import com.police.policedatasystem.model.KeyPerson; +import com.police.policedatasystem.model.PoliceEmergency; +import com.police.policedatasystem.viewmodel.DataViewModel; +import com.scwang.smart.refresh.footer.ClassicsFooter; +import com.scwang.smart.refresh.header.ClassicsHeader; + +import java.util.ArrayList; +import java.util.List; + +public class DataFragment extends Fragment { + public FragmentDataBinding binding; + private DataViewModel viewModel; + private PopupWindow popupWindow; + private PopupWindow popupWindow2; + private PopupWindow popupWindow3; + public final List personList = new ArrayList<>(); + public final List policeList = new ArrayList<>(); + public BaseQuickAdapter adapter; + private int currentTabBar = 1; + private int currentTab = 1; + public int filterType = 0; + indexActivity act; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + binding = FragmentDataBinding.inflate(inflater); + initView(); + Activity activity = getActivity(); + if (activity instanceof indexActivity) { + act = (indexActivity) activity; + } + viewModel = new DataViewModel(this, act); + initListener(); + return binding.getRoot(); + } + + private void initView() { + binding.refreshLayout.setRefreshHeader(new ClassicsHeader(getContext())); + binding.refreshLayout.setRefreshFooter(new ClassicsFooter(getContext())); + binding.rvGroup.setLayoutManager(new LinearLayoutManager(getContext())); + keyPersonInitAdapter(); + setPopupWindow(); + setPopupWindow2(); + setPopupWindow3(); + } + + public void initData() { + viewModel.keyPersonInit(); + viewModel.getKeyPersonMessageCount(); + } + + @Override + public void onResume() { + super.onResume(); + if (!act.findAddress) { + act.requestClient.init(); + } else { + initData(); + } + } + + private void initListener() { + //重点人,案情,案件,点击事件 + binding.llKeyPerson.setOnClickListener(view -> tabBarOnClick(1)); + binding.llPoliceEmergency.setOnClickListener(view -> tabBarOnClick(2)); + binding.llCaseDetails.setOnClickListener(view -> tabBarOnClick(3)); + //搜索按钮添加点击事件 + binding.tvSearchBtn.setOnClickListener(view -> { + if (!act.findAddress) return; + if (currentTabBar == 1) { + if (currentTab == 1) { + viewModel.keyPersonInit(); + } else { + viewModel.orgKeyPersonInit(); + } + } else if (currentTabBar == 2) { + viewModel.policeEmergencyInit(); + } + }); + //我的重点人与区域重点人tab点击切换事件 + binding.llMyKeyPerson.setOnClickListener(view -> tabOnClick(1)); + binding.llAreaKeyPerson.setOnClickListener(view -> tabOnClick(2)); + //loading视图设置空的点击事件 + binding.rlLoading.setOnClickListener(view -> { + }); + //筛选文字下拉菜单按钮点击事件 + binding.typeGroup.setOnClickListener(view -> { + if (!act.findAddress) return; + if (currentTabBar == 1) { + popupWindow.showAsDropDown(binding.typeGroup); + } else if (currentTabBar == 2) { + popupWindow2.showAsDropDown(binding.typeGroup); + } else { + popupWindow3.showAsDropDown(binding.typeGroup); + } + + }); + //重点人列表条目点击事件 + adapter.setOnItemClickListener((adapter1, view, position) -> viewModel.keyPersonDetail(personList.get(position).getSfzh())); + //刷新列表 + binding.refreshLayout.setOnRefreshListener(refreshlayout -> { + if (currentTabBar == 1) { + if (currentTab == 1) { + viewModel.keyPersonRefresh(); + } else { + viewModel.orgKeyPersonRefresh(); + } + return; + } + if (currentTabBar == 2) { + viewModel.policeEmergencyRefresh(); + return; + } + if (currentTabBar == 3) { + if (currentTab == 1) { + viewModel.keyPersonRefresh(); + } else { + viewModel.orgKeyPersonRefresh(); + } + } + }); + //加载更多 + binding.refreshLayout.setOnLoadMoreListener(refreshlayout -> { + if (currentTabBar == 1) { + if (currentTab == 1) { + viewModel.keyPersonLoadMore(); + } else { + viewModel.orgKeyPersonLoadMore(); + } + return; + } + if (currentTabBar == 2) { + viewModel.policeEmergencyLoadMore(); + } + }); + } + + private void keyPersonInitAdapter() { + adapter = new KeyPersonAdapter(); + adapter.setNewInstance(personList); + binding.rvGroup.setAdapter(adapter); + adapter.setOnItemClickListener((adapter1, view, position) -> viewModel.keyPersonDetail(personList.get(position).getSfzh())); + } + + private void policeEmergencyInitAdapter() { + adapter = new PoliceEmergencyAdapter(); + adapter.setNewInstance(policeList); + binding.rvGroup.setAdapter(adapter); + adapter.setOnItemClickListener((adapter1, view, position) -> viewModel.policeEmergencyDetail(policeList.get(position).getJcjbh())); + } + + /** + * tab按钮点击切换 + * + * @param i + */ + private void tabOnClick(int i) { + //如果点击tab与当前的一致,当前点击事件无效. + if (currentTab == i) return; + currentTab = i; + //清空搜索框内容 + binding.etInput.setText(""); + //切换效果设置 + binding.tvAreaKeyPerson.setTextColor(getResources().getColor(R.color.color_666)); + binding.selectAreaKeyPerson.setBackgroundColor(getResources().getColor(R.color.transparent_color)); + binding.tvMyKeyPerson.setTextColor(getResources().getColor(R.color.color_666)); + binding.selectMyKeyPerson.setBackgroundColor(getResources().getColor(R.color.transparent_color)); + if (i == 1) { + binding.tvMyKeyPerson.setTextColor(getResources().getColor(R.color.selected_color)); + binding.selectMyKeyPerson.setBackgroundColor(getResources().getColor(R.color.selected_color)); + } else { + binding.tvAreaKeyPerson.setTextColor(getResources().getColor(R.color.selected_color)); + binding.selectAreaKeyPerson.setBackgroundColor(getResources().getColor(R.color.selected_color)); + } + if (currentTabBar == 1) { + if (currentTab == 1) { + //加载我的重点人 + viewModel.keyPersonInit(); + } else { + viewModel.orgKeyPersonInit(); + } + } + } + + /** + * 顶部tabBar切换 + * + * @param i + */ + private void tabBarOnClick(int i) { + if (currentTabBar == i) return; + currentTabBar = i; + binding.etInput.setText(""); + binding.iconKeyPerson.setBackgroundResource(R.drawable.mine_icon); + binding.tvKeyPerson.setTextColor(getResources().getColor(R.color.black)); + binding.selectKeyPerson.setBackgroundColor(getResources().getColor(R.color.white)); + binding.iconPoliceEmergency.setBackgroundResource(R.drawable.huizhang_icon); + binding.tvPoliceEmergency.setTextColor(getResources().getColor(R.color.black)); + binding.selectPoliceEmergency.setBackgroundColor(getResources().getColor(R.color.white)); + binding.iconCaseDetails.setBackgroundResource(R.drawable.wenjianjia_icon); + binding.tvCaseDetails.setTextColor(getResources().getColor(R.color.black)); + binding.selectCaseDetails.setBackgroundColor(getResources().getColor(R.color.white)); + filterType = 0; + switch (i) { + case 1: + binding.iconKeyPerson.setBackgroundResource(R.drawable.mine_normal); + binding.tvKeyPerson.setTextColor(getResources().getColor(R.color.selected_color)); + binding.selectKeyPerson.setBackgroundColor(getResources().getColor(R.color.selected_color)); + binding.tvSearchTitle.setText("姓名"); + keyPersonInitAdapter(); + if (currentTab == 1) { + viewModel.keyPersonInit(); + } else { + viewModel.orgKeyPersonInit(); + } + binding.tvMyKeyPerson.setText("我的重点人"); + binding.tvAreaKeyPerson.setText("辖区(警种)重点人"); + binding.tabGroup.setVisibility(View.VISIBLE); + break; + case 2: + binding.iconPoliceEmergency.setBackgroundResource(R.drawable.huizhang); + binding.tvPoliceEmergency.setTextColor(getResources().getColor(R.color.selected_color)); + binding.selectPoliceEmergency.setBackgroundColor(getResources().getColor(R.color.selected_color)); + binding.tvSearchTitle.setText("警情编号"); + policeEmergencyInitAdapter(); + viewModel.policeEmergencyInit(); + binding.tabGroup.setVisibility(View.GONE); + break; + default: + binding.iconCaseDetails.setBackgroundResource(R.drawable.wenjianjia); + binding.tvCaseDetails.setTextColor(getResources().getColor(R.color.selected_color)); + binding.selectCaseDetails.setBackgroundColor(getResources().getColor(R.color.selected_color)); + binding.tvSearchTitle.setText("案件编号"); + binding.tvMyKeyPerson.setText("在办案件"); + binding.tvAreaKeyPerson.setText("历史案件"); + binding.tabGroup.setVisibility(View.GONE); + loadCase(new ArrayList<>()); + } + + } + + /** + * 加载案情布局 + */ + public void loadCase(List data) { + KeyPersonAdapter adapter = new KeyPersonAdapter(); + adapter.setNewInstance(data); + binding.rvGroup.setLayoutManager(new LinearLayoutManager(getContext())); + binding.rvGroup.setAdapter(adapter); + adapter.setOnItemClickListener((adapter1, view, position) -> { + viewModel.keyPersonDetail(data.get(position).getSfzh()); + }); + } + + public void loadingShow() { + getActivity().runOnUiThread(() -> binding.rlLoading.setVisibility(View.VISIBLE)); + + } + + public void loadingNone() { + getActivity().runOnUiThread(() -> binding.rlLoading.setVisibility(View.GONE)); + } + + private void setPopupWindow() { + // 初始化 PopupWindow + popupWindow = new PopupWindow(getContext()); + // 加载自定义布局 + LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View contentView = inflater.inflate(R.layout.dropdown_layout, null); + // 设置 PopupWindow 的宽高 + popupWindow.setWidth(LinearLayout.LayoutParams.WRAP_CONTENT); + popupWindow.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT); + // 设置 PopupWindow 的背景 + popupWindow.setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); + // 设置 PopupWindow 显示的位置(相对于按钮) + popupWindow.showAtLocation(binding.typeGroup, Gravity.NO_GRAVITY, 0, 0); + // 为每个菜单项设置点击事件 + TextView textView1 = contentView.findViewById(R.id.textView1); // 假设这是菜单项1的ID + TextView textView2 = contentView.findViewById(R.id.textView2); // 假设这是菜单项2的ID + textView1.setOnClickListener(v -> { + // 处理菜单项 1 的点击事件 + binding.tvSearchTitle.setText("姓名"); + filterType = 0; + popupWindow.dismiss(); // 关闭 PopupWindow + }); + textView2.setOnClickListener(v -> { + // 处理菜单项 2 的点击事件 + binding.tvSearchTitle.setText("身份证号"); + filterType = 1; + popupWindow.dismiss(); // 关闭 PopupWindow + }); + // 将自定义布局设置为 PopupWindow 的内容视图 + popupWindow.setContentView(contentView); + // 设置 PopupWindow 的焦点 + popupWindow.setFocusable(true); + popupWindow.setOutsideTouchable(true); // 设置点击 PopupWindow 外部区域使其消失 + } + + private void setPopupWindow2() { + // 初始化 PopupWindow + popupWindow2 = new PopupWindow(getContext()); + // 加载自定义布局 + LayoutInflater inflater2 = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View contentView2 = inflater2.inflate(R.layout.dropdown_layout2, null); + // 设置 PopupWindow 的宽高 + popupWindow2.setWidth(LinearLayout.LayoutParams.WRAP_CONTENT); + popupWindow2.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT); + // 设置 PopupWindow 的背景 + popupWindow2.setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); + // 设置 PopupWindow 显示的位置(相对于按钮) + popupWindow2.showAtLocation(binding.typeGroup, Gravity.NO_GRAVITY, 0, 0); + // 为每个菜单项设置点击事件 + TextView textView3 = contentView2.findViewById(R.id.textView3); // 假设这是菜单项1的ID + TextView textView4 = contentView2.findViewById(R.id.textView4); // 假设这是菜单项2的ID + TextView textView5 = contentView2.findViewById(R.id.textView5); // 假设这是菜单项2的ID + textView3.setOnClickListener(v -> { + // 处理菜单项 1 的点击事件 + binding.tvSearchTitle.setText("警情编号"); + filterType = 0; + popupWindow2.dismiss(); // 关闭 PopupWindow + }); + textView4.setOnClickListener(v -> { + // 处理菜单项 2 的点击事件 + binding.tvSearchTitle.setText("报警内容"); + filterType = 1; + popupWindow2.dismiss(); // 关闭 PopupWindow + }); + textView5.setOnClickListener(v -> { + // 处理菜单项 2 的点击事件 + binding.tvSearchTitle.setText("报警电话"); + filterType = 2; + popupWindow2.dismiss(); // 关闭 PopupWindow + }); + // 将自定义布局设置为 PopupWindow 的内容视图 + popupWindow2.setContentView(contentView2); + // 设置 PopupWindow 的焦点 + popupWindow2.setFocusable(true); + popupWindow2.setOutsideTouchable(true); // 设置点击 PopupWindow 外部区域使其消失 + } + + private void setPopupWindow3() { + // 初始化 PopupWindow + popupWindow3 = new PopupWindow(getContext()); + // 加载自定义布局 + LayoutInflater inflater2 = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View contentView2 = inflater2.inflate(R.layout.dropdown_layout3, null); + // 设置 PopupWindow 的宽高 + popupWindow3.setWidth(LinearLayout.LayoutParams.WRAP_CONTENT); + popupWindow3.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT); + // 设置 PopupWindow 的背景 + popupWindow3.setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); + // 设置 PopupWindow 显示的位置(相对于按钮) + popupWindow3.showAtLocation(binding.typeGroup, Gravity.NO_GRAVITY, 0, 0); + // 为每个菜单项设置点击事件 + TextView textView6 = contentView2.findViewById(R.id.textView6); // 假设这是菜单项1的ID + TextView textView7 = contentView2.findViewById(R.id.textView7); // 假设这是菜单项2的ID + TextView textView8 = contentView2.findViewById(R.id.textView8); // 假设这是菜单项2的ID + TextView textView9 = contentView2.findViewById(R.id.textView9); // 假设这是菜单项2的ID + textView6.setOnClickListener(v -> { + // 处理菜单项 1 的点击事件 + binding.tvSearchTitle.setText("案件编号"); + filterType = 0; + popupWindow3.dismiss(); // 关闭 PopupWindow + }); + textView7.setOnClickListener(v -> { + // 处理菜单项 2 的点击事件 + binding.tvSearchTitle.setText("案件名称"); + filterType = 1; + popupWindow3.dismiss(); // 关闭 PopupWindow + }); + textView8.setOnClickListener(v -> { + // 处理菜单项 2 的点击事件 + binding.tvSearchTitle.setText("嫌疑人姓名"); + filterType = 3; + popupWindow3.dismiss(); // 关闭 PopupWindow + }); + textView9.setOnClickListener(v -> { + // 处理菜单项 2 的点击事件 + binding.tvSearchTitle.setText("受害人姓名"); + filterType = 4; + popupWindow3.dismiss(); // 关闭 PopupWindow + }); + // 将自定义布局设置为 PopupWindow 的内容视图 + popupWindow3.setContentView(contentView2); + // 设置 PopupWindow 的焦点 + popupWindow3.setFocusable(true); + popupWindow3.setOutsideTouchable(true); // 设置点击 PopupWindow 外部区域使其消失 + } +} diff --git a/app/src/main/java/com/police/policedatasystem/fragment/MineFragment.java b/app/src/main/java/com/police/policedatasystem/fragment/MineFragment.java new file mode 100644 index 0000000..92eff44 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/fragment/MineFragment.java @@ -0,0 +1,91 @@ +package com.police.policedatasystem.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.PopupWindow; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import com.police.policedatasystem.R; +import com.police.policedatasystem.databinding.FragmentMineBinding; + +public class MineFragment extends Fragment { + private FragmentMineBinding binding; + private PopupWindow popupWindow; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + binding = FragmentMineBinding.inflate(inflater); + initView(); + return binding.getRoot(); + } + + private void initView() { + setPopupWindow(); + binding.mineTypeGroup.setOnClickListener(view -> { + popupWindow.setWidth(binding.mineTypeGroup.getWidth()); + popupWindow.showAsDropDown(binding.mineTypeGroup); + }); + } + + private void setPopupWindow() { + // 初始化 PopupWindow + popupWindow = new PopupWindow(getContext()); + // 加载自定义布局 + LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View contentView = inflater.inflate(R.layout.dropdown_layout5, null); + // 设置 PopupWindow 的宽高 + popupWindow.setWidth(LinearLayout.LayoutParams.MATCH_PARENT); + popupWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.all_7_fff_bg)); + popupWindow.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT); + // 设置 PopupWindow 的背景 +// popupWindow.setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); + // 设置 PopupWindow 显示的位置(相对于按钮) + popupWindow.showAtLocation(binding.mineTypeGroup, Gravity.NO_GRAVITY, 0, 0); + // 为每个菜单项设置点击事件 + TextView textView1 = contentView.findViewById(R.id.textView1); // 假设这是菜单项1的ID + TextView textView2 = contentView.findViewById(R.id.textView2); // 假设这是菜单项2的ID + TextView textView3 = contentView.findViewById(R.id.textView3); // 假设这是菜单项2的ID + TextView textView4 = contentView.findViewById(R.id.textView4); // 假设这是菜单项2的ID + TextView textView5 = contentView.findViewById(R.id.textView5); // 假设这是菜单项2的ID + textView1.setOnClickListener(v -> { + // 处理菜单项 1 的点击事件 + binding.tvMineSearchTitle.setText("赋能编码"); + popupWindow.dismiss(); // 关闭 PopupWindow + }); + textView2.setOnClickListener(v -> { + // 处理菜单项 2 的点击事件 + binding.tvMineSearchTitle.setText("申请事由"); + popupWindow.dismiss(); // 关闭 PopupWindow + }); + textView3.setOnClickListener(v -> { + // 处理菜单项 2 的点击事件 + binding.tvMineSearchTitle.setText("申请时间"); + popupWindow.dismiss(); // 关闭 PopupWindow + }); + textView4.setOnClickListener(v -> { + // 处理菜单项 2 的点击事件 + binding.tvMineSearchTitle.setText("信息来源"); + popupWindow.dismiss(); // 关闭 PopupWindow + }); + textView5.setOnClickListener(v -> { + // 处理菜单项 2 的点击事件 + binding.tvMineSearchTitle.setText("办理状态"); + popupWindow.dismiss(); // 关闭 PopupWindow + }); + // 将自定义布局设置为 PopupWindow 的内容视图 + popupWindow.setContentView(contentView); + // 设置 PopupWindow 的焦点 + popupWindow.setFocusable(true); + popupWindow.setOutsideTouchable(true); // 设置点击 PopupWindow 外部区域使其消失 + } +} diff --git a/app/src/main/java/com/police/policedatasystem/http/CustomCallBack.java b/app/src/main/java/com/police/policedatasystem/http/CustomCallBack.java new file mode 100644 index 0000000..8235faf --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/http/CustomCallBack.java @@ -0,0 +1,40 @@ +package com.police.policedatasystem.http; + +import androidx.annotation.NonNull; + +import okhttp3.Call; + +public abstract class CustomCallBack { + public abstract void onError(Call call, @NonNull Exception e); + + public abstract void onSuccess(T value); + +// @Override +// public void onFailure(@NonNull Call call, @NonNull IOException e) { +// onError(call, e); +// } +// +// @Override +// public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException { +// if (!response.isSuccessful()) { +// onError(call, new IOException("Unexpected code " + response)); +// return; +// } +// try { +// ResponseParams responseParams = new Gson().fromJson(response.body().string(), ResponseParams.class); +// if ("200".equals(responseParams.getCode())) { +// for (ResponseParams.FieldData item : responseParams.getData().getDataList()) { +// for (ResponseParams.FieldValues i : item.getFieldValues()) { +//// new Gson().fromJson() +//// onSuccess(i.getValue()); +// } +// } +// } else { +// onError(call, new IOException(responseParams.getMessage())); +// } +// } catch (Exception e) { +// onError(call, new IOException("Unexpected code " + response)); +// } +// } + +} diff --git a/app/src/main/java/com/police/policedatasystem/http/RequestClient.java b/app/src/main/java/com/police/policedatasystem/http/RequestClient.java new file mode 100644 index 0000000..d9525b5 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/http/RequestClient.java @@ -0,0 +1,593 @@ +package com.police.policedatasystem.http; + +import static com.police.policedatasystem.util.UaCredentialApi.PARAMS_KEY_UA_APP_CREDENTIAL; +import static com.police.policedatasystem.util.UaCredentialApi.PARAMS_KEY_UA_RET_CODE; +import static com.police.policedatasystem.util.UaCredentialApi.PARAMS_KEY_UA_RET_SUCCESS; +import static com.police.policedatasystem.util.UaCredentialApi.PARAMS_KEY_UA_USER_CREDENTIAL; + +import android.net.Uri; +import android.os.Bundle; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.police.policedatasystem.MyApplication; +import com.police.policedatasystem.http.requestparams.GetKeyPersonDetailParams; +import com.police.policedatasystem.http.requestparams.GetKeyPersonListParams; +import com.police.policedatasystem.http.requestparams.GetKeyPersonMessageCountParams; +import com.police.policedatasystem.http.requestparams.GetOrgKeyPersonListParams; +import com.police.policedatasystem.http.requestparams.GetPoliceEmergencyDetailParams; +import com.police.policedatasystem.http.requestparams.GetPoliceEmergencyListParams; +import com.police.policedatasystem.http.requestparams.RequestParams; +import com.police.policedatasystem.http.requestparams.ResponseParams; +import com.police.policedatasystem.indexActivity; +import com.police.policedatasystem.model.DataCount; +import com.police.policedatasystem.model.KeyPerson; +import com.police.policedatasystem.model.KeyPersonDetail; +import com.police.policedatasystem.model.PoliceEmergency; +import com.police.policedatasystem.model.PoliceEmergencyDetail; +import com.police.policedatasystem.model.ResourceList; +import com.police.policedatasystem.model.UserCredential; +import com.police.policedatasystem.util.Constants; +import com.police.policedatasystem.util.UiUtils; + +import java.io.IOException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okhttp3.logging.HttpLoggingInterceptor; + +public class RequestClient { + private final indexActivity activity; + private OkHttpClient okHttpClient; + + public RequestClient(indexActivity activity) { + this.activity = activity; + } + + /* + + */ + private void call(String url, RequestParams params, Callback callback) { + try { + RequestBody body = RequestBody.create(new Gson().toJson(params), MediaType.parse("application/json; charset=utf-8")); + Request request = new Request.Builder() + .url(url) + .post(body) + .addHeader("userCredential", URLEncoder.encode(Constants.USER_CREDENTIAL, "UTF-8")) + .addHeader("appCredential", URLEncoder.encode(Constants.APP_CREDENTIAL, "UTF-8")) + .build(); + okHttpClient.newCall(request).enqueue(callback); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + public void init() { + HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); + loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); // 设置日志级别,例如打印请求和响应的body + okHttpClient = new OkHttpClient.Builder() + .addInterceptor(loggingInterceptor) // 添加日志拦截器 + .callTimeout(30, TimeUnit.SECONDS) + .connectTimeout(30, TimeUnit.SECONDS) + .build(); + //获取接口需要用到的凭证 + getInterface(); + } + + //获取接口需要用到的凭证 + private void getInterface() { + Uri uri = Uri.parse("content://com.ydjw.ua.getCredential"); + Bundle params = new Bundle(); + String paramsMessageId = UiUtils.uuid(); + //构建参数 + params.putString("messageId", paramsMessageId);//消息id + params.putString("version", "1");//接口版本号,当前为1 + params.putString("appId", Constants.APP_ID);// + params.putString("orgId", Constants.ORG_ID);// + params.putString("networkAreaCode", "3");// + params.putString("packageName", "com.police.policedatasystem");//应用包名,可空 + //获取票据 + Bundle bundle = MyApplication.getInstance().getContentResolver().call(uri, "", null, params); + //解析结果 + if (bundle == null) { + UiUtils.toast("获取应用凭证失败,bundle为空!"); + return; + } + String messageId = bundle.getString("messageId"); + if (paramsMessageId.equals(messageId)) { + int resultCode = bundle.getInt(PARAMS_KEY_UA_RET_CODE); + if (PARAMS_KEY_UA_RET_SUCCESS == resultCode) { + Constants.APP_CREDENTIAL = bundle.getString(PARAMS_KEY_UA_APP_CREDENTIAL); + Constants.USER_CREDENTIAL = bundle.getString(PARAMS_KEY_UA_USER_CREDENTIAL); + Constants.USER_ID = new Gson().fromJson(Constants.USER_CREDENTIAL, UserCredential.class).getCredential().getLoad().getUserInfo().getJh(); + Constants.SFZH = new Gson().fromJson(Constants.USER_CREDENTIAL, UserCredential.class).getCredential().getLoad().getUserInfo().getSfzh(); + Constants.USER_ORG_ID = new Gson().fromJson(Constants.USER_CREDENTIAL, UserCredential.class).getCredential().getLoad().getUserInfo().getOrgId(); + //根据票据寻址 + findAddress(); + } else { + UiUtils.toast(bundle.getString("message") + ",resultCode:" + resultCode); + } + } else { + UiUtils.toast("获取应用凭证失败,messageId不一致!"); + } + } + + //第二步,寻址 + private void findAddress() { + Thread thread = new Thread(() -> { + // 在这里执行耗时任务 + Uri uri = Uri.parse("content://com.ydjw.rsb.getResourceAddress"); + Bundle bundle = new Bundle(); + String paramsMessageId = UiUtils.uuid(); + bundle.putString("appCredential", Constants.APP_CREDENTIAL);//应用凭证,由上一步获得 + bundle.putString("userCredential", Constants.USER_CREDENTIAL);//用户凭证,由上一步获得 + bundle.putString("version", "1");//服务总线接口版本号,当前为1 + bundle.putString("messageId", paramsMessageId);//消息 ID + Bundle callBack = MyApplication.getInstance().getContentResolver().call(uri, "", null, bundle); + if (callBack == null) { + UiUtils.toast("获取应用资源地址失败,bundle为空"); + return; + } + String messageId = callBack.getString("messageId"); + String resourceList = callBack.getString("resourceList"); + if (paramsMessageId.equals(messageId)) { + int resultCode = callBack.getInt("resultCode"); + if (resultCode == 0) { + if (UiUtils.isEmpty(resourceList)) { + UiUtils.toast("寻址失败,resourceList为空!"); + return; + } + List resourceLists = new Gson().fromJson(resourceList, new TypeToken>() { + }.getType()); + for (ResourceList item : resourceLists) { + Constants.resourceListsMap.put(item.getResourceId(), item); + } + //2.发起请求,获取重点人数据 + activity.initData(); + } else { + if (UiUtils.isEmpty(resourceList)) { + UiUtils.toast("寻址失败,错误码:" + resultCode); + } + } + } + }); + thread.start(); + } + + /** + * 获取重点人 + * + * @param params 参数对象 + * @param callback 回调函数 + */ + public void getKeyPerson(GetKeyPersonListParams params, CustomCallBack> callback) { + ResourceList resourceList = Constants.resourceListsMap.get(Constants.KEY_PERSON_ID); + RequestParams.Condition condition = new RequestParams.Condition(); + condition.setLogicalOperate("and"); + RequestParams.KeyValues keyValues = new RequestParams.KeyValues(); + keyValues.setKey("injson"); + params.setJybh(Constants.USER_ID); + params.setSfhm(Constants.SFZH); + params.setPageSize(Constants.PAGE_SIZE + ""); + keyValues.setValue(new Gson().toJson(params)); + List keyValuesList = new ArrayList<>(); + keyValuesList.add(keyValues); + condition.setKeyValueList(keyValuesList); + RequestParams.Parameter parameter = new RequestParams.Parameter(); + parameter.setCondition(condition); + parameter.setPage(new RequestParams.Page()); + parameter.setFields("outjson"); + parameter.setNetworkCode("3"); + parameter.setOrderBy(null); + parameter.setRegionalismCode(Constants.ORG_ID); + parameter.setDataObjId(Constants.KEY_PERSON_ID); + RequestParams requestParams = new RequestParams(); + requestParams.setMessageId(UiUtils.uuid()); + requestParams.setVersion("1.0"); + requestParams.setParameter(parameter); + if (resourceList == null) return; + call(resourceList.getResourceAddress(), requestParams, new Callback() { + @Override + public void onFailure(@NonNull Call call, @NonNull IOException e) { + activity.runOnUiThread(() -> callback.onError(call, e)); + // 请求失败 + e.printStackTrace(); + } + + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + try { + // 请求成功,处理响应数据 + String responseBody = response.body().string(); + activity.runOnUiThread(() -> { + if (!response.isSuccessful()) { + callback.onError(call, new IOException("Unexpected code " + response)); + return; + } + ResponseParams responseParams = new Gson().fromJson(responseBody, ResponseParams.class); + if ("200".equals(responseParams.getCode())) { + for (ResponseParams.FieldData item : responseParams.getData().getDataList()) { + for (ResponseParams.FieldValues i : item.getFieldValues()) { + List keyPersonList = new Gson().fromJson(i.getValue(), new TypeToken>() { + }.getType()); + callback.onSuccess(keyPersonList); + } + } + } else { + callback.onError(call, new IOException(responseParams.getMessage())); + } + }); + } catch (Exception e) { + callback.onError(call, e); + e.printStackTrace(); + } + } + }); + } + + /** + * 获取组织重点人数据 + * + * @param params 搜索关键字姓名 + * @param callBack 回调函数 + */ + public void getOrgKeyPerson(GetOrgKeyPersonListParams params, CustomCallBack> callBack) { + ResourceList resourceList = Constants.resourceListsMap.get(Constants.ORG_KEY_PERSON_ID); + RequestParams.Condition condition = new RequestParams.Condition(); + condition.setLogicalOperate("and"); + RequestParams.KeyValues keyValues = new RequestParams.KeyValues(); + keyValues.setKey("injson"); + params.setSfhm(Constants.SFZH); + params.setDept(Constants.USER_ORG_ID); + params.setPageSize(Constants.PAGE_SIZE + ""); + keyValues.setValue(new Gson().toJson(params)); + List keyValuesList = new ArrayList<>(); + keyValuesList.add(keyValues); + condition.setKeyValueList(keyValuesList); + RequestParams.Parameter parameter = new RequestParams.Parameter(); + parameter.setCondition(condition); + parameter.setPage(new RequestParams.Page()); + parameter.setFields("outjson"); + parameter.setNetworkCode("3"); + parameter.setOrderBy(null); + parameter.setRegionalismCode(Constants.ORG_ID); + parameter.setDataObjId(Constants.ORG_KEY_PERSON_ID); + RequestParams requestParams = new RequestParams(); + requestParams.setMessageId(UiUtils.uuid()); + requestParams.setVersion("1.0"); + requestParams.setParameter(parameter); + if (resourceList == null) { + callBack.onError(null, new Exception("寻址数据为空")); + return; + } + + call(resourceList.getResourceAddress(), requestParams, new Callback() { + @Override + public void onFailure(@NonNull Call call, @NonNull IOException e) { + activity.runOnUiThread(() -> callBack.onError(call, e)); + // 请求失败 + e.printStackTrace(); + } + + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (!response.isSuccessful()) { + activity.runOnUiThread(() -> callBack.onError(call, new IOException("Unexpected code " + response))); + return; + } + try { + // 请求成功,处理响应数据 + String responseBody = response.body().string(); + activity.runOnUiThread(() -> { + ResponseParams responseParams = new Gson().fromJson(responseBody, ResponseParams.class); + if ("200".equals(responseParams.getCode())) { + for (ResponseParams.FieldData item : responseParams.getData().getDataList()) { + for (ResponseParams.FieldValues i : item.getFieldValues()) { + List keyPersonList = new Gson().fromJson(i.getValue(), new TypeToken>() { + }.getType()); + callBack.onSuccess(keyPersonList); + } + } + } else { + callBack.onError(call, new Exception(responseParams.getMessage())); + } + }); + } catch (Exception e) { + activity.runOnUiThread(() -> callBack.onError(call, e)); + e.printStackTrace(); + } + + } + }); + } + + + /** + * 获取重点人详情数据 + * + * @param str 身份证号 + */ + public void keyPersonDetail(String str, CustomCallBack callBack) { + ResourceList resourceList = Constants.resourceListsMap.get(Constants.KEY_PERSON_DETAIL_ID); + RequestParams.Condition condition = new RequestParams.Condition(); + condition.setLogicalOperate("and"); + RequestParams.KeyValues keyValues = new RequestParams.KeyValues(); + keyValues.setKey("injson"); + GetKeyPersonDetailParams params = new GetKeyPersonDetailParams(); + params.setSfzh(str);// params.setSfzh("220104197307276911"); + params.setSfhm(Constants.SFZH); + keyValues.setValue(new Gson().toJson(params)); + List keyValuesList = new ArrayList<>(); + keyValuesList.add(keyValues); + condition.setKeyValueList(keyValuesList); + RequestParams.Parameter parameter = new RequestParams.Parameter(); + parameter.setCondition(condition); + parameter.setPage(new RequestParams.Page()); + parameter.setFields("outjson"); + parameter.setNetworkCode("3"); + parameter.setOrderBy(null); + parameter.setRegionalismCode(Constants.ORG_ID); + parameter.setDataObjId(Constants.KEY_PERSON_DETAIL_ID); + RequestParams requestParams = new RequestParams(); + requestParams.setMessageId(UiUtils.uuid()); + requestParams.setVersion("1.0"); + requestParams.setParameter(parameter); + call(resourceList.getResourceAddress(), requestParams, new Callback() { + @Override + public void onFailure(@NonNull Call call, @NonNull IOException e) { + // 请求失败 + e.printStackTrace(); + activity.runOnUiThread(() -> callBack.onError(call, e)); + } + + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (!response.isSuccessful()) { + activity.runOnUiThread(() -> callBack.onError(call, new IOException("Unexpected code " + response))); + return; + } + try { + // 请求成功,处理响应数据 + String responseBody = response.body().string(); + ResponseParams responseParams = new Gson().fromJson(responseBody, ResponseParams.class); + if (!"200".equals(responseParams.getCode())) { + activity.runOnUiThread(() -> callBack.onError(call, new Exception("服务器异常,请联系开发人员或稍后重试!"))); + return; + } + for (ResponseParams.FieldData item : responseParams.getData().getDataList()) { + for (ResponseParams.FieldValues i : item.getFieldValues()) { + KeyPersonDetail keyPersonDetail = new Gson().fromJson(i.getValue(), KeyPersonDetail.class); + activity.runOnUiThread(() -> callBack.onSuccess(keyPersonDetail)); + } + } + } catch (Exception e) { + e.printStackTrace(); + activity.runOnUiThread(() -> callBack.onError(call, e)); + } + } + }); + } + + /** + * 获取警情列表数据 + * + * @param params 参数 + * @param callBack 回调函数 + */ + public void getPoliceEmergency(GetPoliceEmergencyListParams params, CustomCallBack> callBack) { + ResourceList resourceList = Constants.resourceListsMap.get(Constants.POLICE_EMERGENCY_ID); + RequestParams.Condition condition = new RequestParams.Condition(); + condition.setLogicalOperate("and"); + RequestParams.KeyValues keyValues = new RequestParams.KeyValues(); + keyValues.setKey("injson"); + params.setSfhm(Constants.SFZH); +// params.setSfhm("220104198105200331"); + params.setPageSize(Constants.PAGE_SIZE + ""); + keyValues.setValue(new Gson().toJson(params)); + List keyValuesList = new ArrayList<>(); + keyValuesList.add(keyValues); + condition.setKeyValueList(keyValuesList); + RequestParams.Parameter parameter = new RequestParams.Parameter(); + parameter.setCondition(condition); + parameter.setPage(new RequestParams.Page()); + parameter.setFields("outjson"); + parameter.setNetworkCode("3"); + parameter.setOrderBy(null); + parameter.setRegionalismCode(Constants.ORG_ID); + parameter.setDataObjId(Constants.POLICE_EMERGENCY_ID); + RequestParams requestParams = new RequestParams(); + requestParams.setMessageId(UiUtils.uuid()); + requestParams.setVersion("1.0"); + requestParams.setParameter(parameter); + if (resourceList == null) { + callBack.onError(null, new Exception("寻址数据为空")); + return; + } + + call(resourceList.getResourceAddress(), requestParams, new Callback() { + @Override + public void onFailure(@NonNull Call call, @NonNull IOException e) { + activity.runOnUiThread(() -> callBack.onError(call, e)); + // 请求失败 + e.printStackTrace(); + } + + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (!response.isSuccessful()) { + activity.runOnUiThread(() -> callBack.onError(call, new IOException("Unexpected code " + response))); + return; + } + try { + // 请求成功,处理响应数据 + String responseBody = response.body().string(); + activity.runOnUiThread(() -> { + ResponseParams responseParams = new Gson().fromJson(responseBody, ResponseParams.class); + if ("200".equals(responseParams.getCode())) { + for (ResponseParams.FieldData item : responseParams.getData().getDataList()) { + for (ResponseParams.FieldValues i : item.getFieldValues()) { + List keyPersonList = new Gson().fromJson(i.getValue(), new TypeToken>() { + }.getType()); + callBack.onSuccess(keyPersonList); + } + } + } else { + callBack.onError(call, new Exception(responseParams.getMessage())); + } + }); + } catch (Exception e) { + activity.runOnUiThread(() -> callBack.onError(call, e)); + e.printStackTrace(); + } + + } + }); + } + + + /** + * 获取重点人详情数据 + * + * @param str 身份证号 + */ + public void getPoliceEmergencyDetail(String str, CustomCallBack callBack) { + ResourceList resourceList = Constants.resourceListsMap.get(Constants.POLICE_EMERGENCY_DETAIL_ID); + RequestParams.Condition condition = new RequestParams.Condition(); + condition.setLogicalOperate("and"); + RequestParams.KeyValues keyValues = new RequestParams.KeyValues(); + keyValues.setKey("injson"); + GetPoliceEmergencyDetailParams params = new GetPoliceEmergencyDetailParams(); + params.setJcjbh(str);// params.setSfzh("220104197307276911"); + params.setSfhm(Constants.SFZH); + keyValues.setValue(new Gson().toJson(params)); + List keyValuesList = new ArrayList<>(); + keyValuesList.add(keyValues); + condition.setKeyValueList(keyValuesList); + RequestParams.Parameter parameter = new RequestParams.Parameter(); + parameter.setCondition(condition); + parameter.setPage(new RequestParams.Page()); + parameter.setFields("outjson"); + parameter.setNetworkCode("3"); + parameter.setOrderBy(null); + parameter.setRegionalismCode(Constants.ORG_ID); + parameter.setDataObjId(Constants.POLICE_EMERGENCY_DETAIL_ID); + RequestParams requestParams = new RequestParams(); + requestParams.setMessageId(UiUtils.uuid()); + requestParams.setVersion("1.0"); + requestParams.setParameter(parameter); + call(resourceList.getResourceAddress(), requestParams, new Callback() { + @Override + public void onFailure(@NonNull Call call, @NonNull IOException e) { + // 请求失败 + e.printStackTrace(); + activity.runOnUiThread(() -> callBack.onError(call, e)); + } + + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (!response.isSuccessful()) { + activity.runOnUiThread(() -> callBack.onError(call, new IOException("Unexpected code " + response))); + return; + } + try { + // 请求成功,处理响应数据 + String responseBody = response.body().string(); + ResponseParams responseParams = new Gson().fromJson(responseBody, ResponseParams.class); + if (!"200".equals(responseParams.getCode())) { + activity.runOnUiThread(() -> callBack.onError(call, new Exception("服务器异常,请联系开发人员或稍后重试!"))); + return; + } + for (ResponseParams.FieldData item : responseParams.getData().getDataList()) { + for (ResponseParams.FieldValues i : item.getFieldValues()) { + PoliceEmergencyDetail keyPersonDetail = new Gson().fromJson(i.getValue(), PoliceEmergencyDetail.class); + activity.runOnUiThread(() -> callBack.onSuccess(keyPersonDetail)); + } + } + } catch (Exception e) { + e.printStackTrace(); + activity.runOnUiThread(() -> callBack.onError(call, e)); + } + } + }); + } + + /** + * 获取重点人数据统计 + */ + public void getKeyPersonMessageCount(CustomCallBack callBack) { + ResourceList resourceList = Constants.resourceListsMap.get(Constants.KEY_PERSON_MESSAGE_COUNT_ID); + RequestParams.Condition condition = new RequestParams.Condition(); + condition.setLogicalOperate("and"); + RequestParams.KeyValues keyValues = new RequestParams.KeyValues(); + keyValues.setKey("injson"); + GetKeyPersonMessageCountParams params = new GetKeyPersonMessageCountParams(); + params.setSfhm(Constants.SFZH); + params.setJybh(Constants.USER_ID); + params.setDept(Constants.USER_ORG_ID); +// params.setSfhm("220104198105200331"); +// params.setDept(Constants.USER_ORG_ID); +// params.setJybh("106222"); + keyValues.setValue(new Gson().toJson(params)); + List keyValuesList = new ArrayList<>(); + keyValuesList.add(keyValues); + condition.setKeyValueList(keyValuesList); + RequestParams.Parameter parameter = new RequestParams.Parameter(); + parameter.setCondition(condition); + parameter.setPage(new RequestParams.Page()); + parameter.setFields("outjson"); + parameter.setNetworkCode("3"); + parameter.setOrderBy(null); + parameter.setRegionalismCode(Constants.ORG_ID); + parameter.setDataObjId(Constants.KEY_PERSON_MESSAGE_COUNT_ID); + RequestParams requestParams = new RequestParams(); + requestParams.setMessageId(UiUtils.uuid()); + requestParams.setVersion("1.0"); + requestParams.setParameter(parameter); + call(resourceList.getResourceAddress(), requestParams, new Callback() { + @Override + public void onFailure(@NonNull Call call, @NonNull IOException e) { + // 请求失败 + e.printStackTrace(); + activity.runOnUiThread(() -> callBack.onError(call, e)); + } + + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (!response.isSuccessful()) { + activity.runOnUiThread(() -> callBack.onError(call, new IOException("Unexpected code " + response))); + return; + } + try { + // 请求成功,处理响应数据 + String responseBody = response.body().string(); + ResponseParams responseParams = new Gson().fromJson(responseBody, ResponseParams.class); + if (!"200".equals(responseParams.getCode())) { + activity.runOnUiThread(() -> callBack.onError(call, new Exception("服务器异常,请联系开发人员或稍后重试!"))); + return; + } + for (ResponseParams.FieldData item : responseParams.getData().getDataList()) { + for (ResponseParams.FieldValues i : item.getFieldValues()) { + DataCount dataCount = new Gson().fromJson(i.getValue(), DataCount.class); + activity.runOnUiThread(() -> callBack.onSuccess(dataCount)); + } + } + } catch (Exception e) { + e.printStackTrace(); + activity.runOnUiThread(() -> callBack.onError(call, e)); + } + } + }); + } +} diff --git a/app/src/main/java/com/police/policedatasystem/http/requestparams/GetKeyPersonDetailParams.java b/app/src/main/java/com/police/policedatasystem/http/requestparams/GetKeyPersonDetailParams.java new file mode 100644 index 0000000..a497e26 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/http/requestparams/GetKeyPersonDetailParams.java @@ -0,0 +1,45 @@ +package com.police.policedatasystem.http.requestparams; + +import java.io.Serializable; + +/** + * {"dept" : "220521950000","messageId":"12","version":"1.0" + */ +public class GetKeyPersonDetailParams implements Serializable { + private String sfzh="222304195909250034"; + private String messageId; + private String version; + private String sfhm; + + public String getSfhm() { + return sfhm; + } + + public void setSfhm(String sfhm) { + this.sfhm = sfhm; + } + + public String getSfzh() { + return sfzh; + } + + public void setSfzh(String sfzh) { + this.sfzh = sfzh; + } + + public String getMessageId() { + return messageId; + } + + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} diff --git a/app/src/main/java/com/police/policedatasystem/http/requestparams/GetKeyPersonListParams.java b/app/src/main/java/com/police/policedatasystem/http/requestparams/GetKeyPersonListParams.java new file mode 100644 index 0000000..3a6b256 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/http/requestparams/GetKeyPersonListParams.java @@ -0,0 +1,89 @@ +package com.police.policedatasystem.http.requestparams; + +import java.io.Serializable; + +/** + * {"jybh" : "840364","messageId":"12","version":"1.0" + */ +public class GetKeyPersonListParams implements Serializable { + private String jybh;//警员编号 + private String xm = "";//姓名 + private String sfzh = "";//身份证号 + private String messageId; + private String version; + private String pageNum; + private String pageSize; + private String sfhm;//当前用户的身份号码 + + public String getSfhm() { + return sfhm; + } + + public void setSfhm(String sfhm) { + this.sfhm = sfhm; + } + + public String getPageNum() { + return pageNum; + } + + public void setPageNum(String pageNum) { + this.pageNum = pageNum; + } + + public String getPageSize() { + return pageSize; + } + + public void setPageSize(String pageSize) { + this.pageSize = pageSize; + } + + public String getXm() { + return xm; + } + + public void setXm(String xm) { + this.xm = xm; + } + + public String getSfzh() { + return sfzh; + } + + public void setSfzh(String sfzh) { + this.sfzh = sfzh; + } + + public GetKeyPersonListParams(String jybh) { + this.jybh = jybh; + } + + public GetKeyPersonListParams() { + this.jybh = jybh; + } + + public String getJybh() { + return jybh; + } + + public void setJybh(String jybh) { + this.jybh = jybh; + } + + public String getMessageId() { + return messageId; + } + + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} diff --git a/app/src/main/java/com/police/policedatasystem/http/requestparams/GetKeyPersonMessageCountParams.java b/app/src/main/java/com/police/policedatasystem/http/requestparams/GetKeyPersonMessageCountParams.java new file mode 100644 index 0000000..5bf90e3 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/http/requestparams/GetKeyPersonMessageCountParams.java @@ -0,0 +1,80 @@ +package com.police.policedatasystem.http.requestparams; + +import java.io.Serializable; + +/** + * {"jybh" : "840364","messageId":"12","version":"1.0" + */ +public class GetKeyPersonMessageCountParams implements Serializable { + private String jybh;//警员编号 + private String sfhm = "";//身份证号 + private String dept = "";//组织机构 + private String messageId; + private String version; + private String pageNum; + private String pageSize; + + public String getSfhm() { + return sfhm; + } + + public void setSfhm(String sfhm) { + this.sfhm = sfhm; + } + + public String getPageNum() { + return pageNum; + } + + public void setPageNum(String pageNum) { + this.pageNum = pageNum; + } + + public String getPageSize() { + return pageSize; + } + + public void setPageSize(String pageSize) { + this.pageSize = pageSize; + } + + public GetKeyPersonMessageCountParams(String jybh) { + this.jybh = jybh; + } + + public GetKeyPersonMessageCountParams() { + this.jybh = jybh; + } + + public String getJybh() { + return jybh; + } + + public String getDept() { + return dept; + } + + public void setDept(String dept) { + this.dept = dept; + } + + public void setJybh(String jybh) { + this.jybh = jybh; + } + + public String getMessageId() { + return messageId; + } + + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} diff --git a/app/src/main/java/com/police/policedatasystem/http/requestparams/GetOrgKeyPersonListParams.java b/app/src/main/java/com/police/policedatasystem/http/requestparams/GetOrgKeyPersonListParams.java new file mode 100644 index 0000000..e2023e2 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/http/requestparams/GetOrgKeyPersonListParams.java @@ -0,0 +1,81 @@ +package com.police.policedatasystem.http.requestparams; + +import java.io.Serializable; + +/** + * {"dept" : "220521950000","messageId":"12","version":"1.0" + */ +public class GetOrgKeyPersonListParams implements Serializable { + private String dept; + private String xm; + private String sfzh; + private String messageId; + private String version; + private String pageNum; + private String pageSize; + private String sfhm; + + public String getSfhm() { + return sfhm; + } + + public void setSfhm(String sfhm) { + this.sfhm = sfhm; + } + + public String getPageNum() { + return pageNum; + } + + public void setPageNum(String pageNum) { + this.pageNum = pageNum; + } + + public String getPageSize() { + return pageSize; + } + + public void setPageSize(String pageSize) { + this.pageSize = pageSize; + } + + public String getXm() { + return xm; + } + + public void setXm(String xm) { + this.xm = xm; + } + + public String getSfzh() { + return sfzh; + } + + public void setSfzh(String sfzh) { + this.sfzh = sfzh; + } + + public String getDept() { + return dept; + } + + public void setDept(String dept) { + this.dept = dept; + } + + public String getMessageId() { + return messageId; + } + + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} diff --git a/app/src/main/java/com/police/policedatasystem/http/requestparams/GetPoliceEmergencyDetailParams.java b/app/src/main/java/com/police/policedatasystem/http/requestparams/GetPoliceEmergencyDetailParams.java new file mode 100644 index 0000000..d198b23 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/http/requestparams/GetPoliceEmergencyDetailParams.java @@ -0,0 +1,45 @@ +package com.police.policedatasystem.http.requestparams; + +import java.io.Serializable; + +/** + * {"dept" : "220521950000","messageId":"12","version":"1.0" + */ +public class GetPoliceEmergencyDetailParams implements Serializable { + private String jcjbh="222304195909250034"; + private String messageId; + private String version; + private String sfhm; + + public String getSfhm() { + return sfhm; + } + + public void setSfhm(String sfhm) { + this.sfhm = sfhm; + } + + public String getJcjbh() { + return jcjbh; + } + + public void setJcjbh(String jcjbh) { + this.jcjbh = jcjbh; + } + + public String getMessageId() { + return messageId; + } + + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} diff --git a/app/src/main/java/com/police/policedatasystem/http/requestparams/GetPoliceEmergencyListParams.java b/app/src/main/java/com/police/policedatasystem/http/requestparams/GetPoliceEmergencyListParams.java new file mode 100644 index 0000000..a054da1 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/http/requestparams/GetPoliceEmergencyListParams.java @@ -0,0 +1,81 @@ +package com.police.policedatasystem.http.requestparams; + +import java.io.Serializable; + +/** + * {"jybh" : "840364","messageId":"12","version":"1.0" + */ +public class GetPoliceEmergencyListParams implements Serializable { + private String sfhm; + private String bjjyqk = "";//报警内容 + private String jcjbh = "";//警情编号 + private String bjrlxdh = "";//报警电话 + private String messageId; + private String version; + private String pageNum; + private String pageSize; + + public String getPageNum() { + return pageNum; + } + + public void setPageNum(String pageNum) { + this.pageNum = pageNum; + } + + public String getPageSize() { + return pageSize; + } + + public void setPageSize(String pageSize) { + this.pageSize = pageSize; + } + + public String getSfhm() { + return sfhm; + } + + public void setSfhm(String sfhm) { + this.sfhm = sfhm; + } + + public String getMessageId() { + return messageId; + } + + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getBjjyqk() { + return bjjyqk; + } + + public void setBjjyqk(String bjjyqk) { + this.bjjyqk = bjjyqk; + } + + public String getJcjbh() { + return jcjbh; + } + + public void setJcjbh(String jcjbh) { + this.jcjbh = jcjbh; + } + + public String getBjrlxdh() { + return bjrlxdh; + } + + public void setBjrlxdh(String bjrlxdh) { + this.bjrlxdh = bjrlxdh; + } +} diff --git a/app/src/main/java/com/police/policedatasystem/http/requestparams/RequestParams.java b/app/src/main/java/com/police/policedatasystem/http/requestparams/RequestParams.java new file mode 100644 index 0000000..795ce3a --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/http/requestparams/RequestParams.java @@ -0,0 +1,156 @@ +package com.police.policedatasystem.http.requestparams; + +import java.io.Serializable; +import java.util.List; + +public class RequestParams implements Serializable { + private String messageId;//自定义唯一值,建议 UUID.randomUUID().toString() + private String version;//服务总线版本号,目前填写 1.0 即可 + private Parameter parameter;//结构体中参数释义如下 + + public String getMessageId() { + return messageId; + } + + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public Parameter getParameter() { + return parameter; + } + + public void setParameter(Parameter parameter) { + this.parameter = parameter; + } + + public static class Page { + public int pageSize = 1; + public int pageNo = 1; + } + + public static class Parameter implements Serializable { + private Condition condition;//(条件)结构体释义如下 + private String dataObjId; //应用商店注册对应的资源 id + private String fields;//后台约定字段,可咨询后台开发人员 + private String networkCode;//网络类型,应用商店注册对应的网络类型 + private String orderBy;//排序字段,可空 + private Page page;//页码信息,非空 + private String regionalismCode; //区域代码 应用商店注册 app 对应的区域代码 + + public Condition getCondition() { + return condition; + } + + public void setCondition(Condition condition) { + this.condition = condition; + } + + public String getDataObjId() { + return dataObjId; + } + + public void setDataObjId(String dataObjId) { + this.dataObjId = dataObjId; + } + + public String getFields() { + return fields; + } + + public void setFields(String fields) { + this.fields = fields; + } + + public String getNetworkCode() { + return networkCode; + } + + public void setNetworkCode(String networkCode) { + this.networkCode = networkCode; + } + + public String getOrderBy() { + return orderBy; + } + + public void setOrderBy(String orderBy) { + this.orderBy = orderBy; + } + + public Page getPage() { + return page; + } + + public void setPage(Page page) { + this.page = page; + } + + public String getRegionalismCode() { + return regionalismCode; + } + + public void setRegionalismCode(String regionalismCode) { + this.regionalismCode = regionalismCode; + } + } + + public static class Condition implements Serializable { + private String logicalOperate = "and";//操作符,传值 and + private List keyValueList;//集合,里面装的键值对,字段解释如下 + + public String getLogicalOperate() { + return logicalOperate; + } + + public void setLogicalOperate(String logicalOperate) { + this.logicalOperate = logicalOperate; + } + + public List getKeyValueList() { + return keyValueList; + } + + public void setKeyValueList(List keyValueList) { + this.keyValueList = keyValueList; + } + } + + public static class KeyValues implements Serializable { + private String key;//跟后台约定,你想放在服务总线接口里面入参的 key + private String value;//自己后台接口需要的入参实际值,可放自己接口需要的 json 值 + private String relationOperator = "=";//关系符 传= + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getRelationOperator() { + return relationOperator; + } + + public void setRelationOperator(String relationOperator) { + this.relationOperator = relationOperator; + } + } +} diff --git a/app/src/main/java/com/police/policedatasystem/http/requestparams/ResponseParams.java b/app/src/main/java/com/police/policedatasystem/http/requestparams/ResponseParams.java new file mode 100644 index 0000000..8b525ac --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/http/requestparams/ResponseParams.java @@ -0,0 +1,96 @@ +package com.police.policedatasystem.http.requestparams; + +import java.io.Serializable; +import java.util.List; + +public class ResponseParams implements Serializable { + String messageId;//自定义唯一值,建议 UUID.randomUUID().toString() + String message;// + String version;//服务总线版本号,目前填写 1.0 即可 + String code;//结构体中参数释义如下 + Data data; + public String getMessageId() { + return messageId; + } + + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public Data getData() { + return data; + } + + public void setData(Data data) { + this.data = data; + } + + public static class Data implements Serializable { + private List dataList;//(条件)结构体释义如下 + + public List getDataList() { + return dataList; + } + + public void setDataList(List dataList) { + this.dataList = dataList; + } + } + + public static class FieldData implements Serializable { + private List fieldValues; + + public List getFieldValues() { + return fieldValues; + } + + public void setFieldValues(List fieldValues) { + this.fieldValues = fieldValues; + } + } + + public static class FieldValues implements Serializable { + private String field; + private String value; + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/app/src/main/java/com/police/policedatasystem/indexActivity.java b/app/src/main/java/com/police/policedatasystem/indexActivity.java new file mode 100644 index 0000000..bb11b57 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/indexActivity.java @@ -0,0 +1,132 @@ +package com.police.policedatasystem; + + +import static com.police.policedatasystem.util.UaCredentialApi.ACTION_SUFFIX_UA_LOGIN; +import static com.police.policedatasystem.util.UaCredentialApi.ACTION_UA_LOGOUT; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.text.TextUtils; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentTransaction; + +import com.police.policedatasystem.databinding.ActivityIndexBinding; +import com.police.policedatasystem.fragment.ApplyFragment; +import com.police.policedatasystem.fragment.DataFragment; +import com.police.policedatasystem.fragment.MineFragment; +import com.police.policedatasystem.http.RequestClient; +import com.police.policedatasystem.util.Constants; +import com.police.policedatasystem.viewmodel.IndexViewModel; + +public class indexActivity extends AppCompatActivity { + public ActivityIndexBinding binding; + private IndexViewModel viewModel; + public RequestClient requestClient; + public boolean findAddress = false; + private DataFragment dataFragment; + private ApplyFragment applyFragment; + private MineFragment mineFragment; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityIndexBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + initView(); + viewModel = new IndexViewModel(this); + requestClient = new RequestClient(this); + } + + private void initView() { + dataFragment = new DataFragment(); + applyFragment = new ApplyFragment(); + mineFragment = new MineFragment(); + binding.navBarGroup.navBar1.setOnClickListener(view -> { + replaceFragment(dataFragment); + binding.navBarGroup.navBarIcon1.setImageResource(R.mipmap.icon_data_selected); + binding.navBarGroup.navBarText1.setTextColor(getColor(R.color.selected_color)); + binding.navBarGroup.navBarIcon2.setImageResource(R.mipmap.icon_apply_normal); + binding.navBarGroup.navBarText2.setTextColor(getColor(R.color.normal_color)); + binding.navBarGroup.navBarIcon3.setImageResource(R.mipmap.icon_mine_normal); + binding.navBarGroup.navBarText3.setTextColor(getColor(R.color.normal_color)); + }); + binding.navBarGroup.navBar2.setOnClickListener(view -> { + replaceFragment(applyFragment); + binding.navBarGroup.navBarIcon1.setImageResource(R.mipmap.icon_data_normal); + binding.navBarGroup.navBarText1.setTextColor(getColor(R.color.normal_color)); + binding.navBarGroup.navBarIcon2.setImageResource(R.mipmap.icon_apply_selected); + binding.navBarGroup.navBarText2.setTextColor(getColor(R.color.selected_color)); + binding.navBarGroup.navBarIcon3.setImageResource(R.mipmap.icon_mine_normal); + binding.navBarGroup.navBarText3.setTextColor(getColor(R.color.normal_color)); + }); + binding.navBarGroup.navBar3.setOnClickListener(view -> { + replaceFragment(mineFragment); + binding.navBarGroup.navBarIcon1.setImageResource(R.mipmap.icon_data_normal); + binding.navBarGroup.navBarText1.setTextColor(getColor(R.color.normal_color)); + binding.navBarGroup.navBarIcon2.setImageResource(R.mipmap.icon_apply_normal); + binding.navBarGroup.navBarText2.setTextColor(getColor(R.color.normal_color)); + binding.navBarGroup.navBarIcon3.setImageResource(R.mipmap.icon_mine_selected); + binding.navBarGroup.navBarText3.setTextColor(getColor(R.color.selected_color)); + }); + replaceFragment(dataFragment); + registerBroadcastReceiver(); + } + + public void initData() { + //改变寻址状态,走到这里证明寻址成功了 + if (findAddress) return; + findAddress = true; + binding.wmWm.setTextSize(50); + binding.wmWm.setText(Constants.SFZH); + dataFragment.initData(); + } + + private void replaceFragment(Fragment newFragment) { + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + transaction.replace(R.id.fc_view, newFragment); + transaction.commit(); + } + + private void registerBroadcastReceiver() { + IntentFilter intentFilter = new IntentFilter(); + String pkgName = getPackageName(); + /**添加登录成功事件监听 + * 当第一次登录,调用【IF-UA-SDK-01】接口可能返回"票据不存在",此时需要注册监听此事件, + * 当登录成功后,接收到此事件即可重新调用【IF-UA-SDK-01】获取相关票据 + * */ + intentFilter.addAction(pkgName + ACTION_SUFFIX_UA_LOGIN); + + /**增加登出事件监听 + * 当UA主动账户退出时会发送该事件,此时已经登录应用可以根据自身业务实施退出 + * */ + intentFilter.addAction(pkgName + ACTION_UA_LOGOUT); + registerReceiver(uaLoginInReceiver, intentFilter); + } + + private final BroadcastReceiver uaLoginInReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (TextUtils.isEmpty(action)) { + return; + } + if (action.contains(ACTION_SUFFIX_UA_LOGIN)) { + //再次获取票据 + if (requestClient != null) { + requestClient.init(); + } + return; + } + if (action.contains(ACTION_UA_LOGOUT)) { + //程序退出 + startActivity(new Intent(indexActivity.this, indexActivity.class)); + finish(); + } + } + }; +} \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/model/DataCount.java b/app/src/main/java/com/police/policedatasystem/model/DataCount.java new file mode 100644 index 0000000..b0a24ed --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/model/DataCount.java @@ -0,0 +1,49 @@ +package com.police.policedatasystem.model; + +import java.io.Serializable; + +/** + * + */ +public class DataCount implements Serializable { + //重点人 + private String zdryCount = "0"; + //警情 + private String jqCount = "0"; + //案情 + private String aqCount = "0"; + //辖区 + private String zdryDeptCount = "0"; + + public String getZdryCount() { + return zdryCount; + } + + public void setZdryCount(String zdryCount) { + this.zdryCount = zdryCount; + } + + public String getJqCount() { + return jqCount; + } + + public void setJqCount(String jqCount) { + this.jqCount = jqCount; + } + + public String getAqCount() { + return aqCount; + } + + public void setAqCount(String aqCount) { + this.aqCount = aqCount; + } + + public String getZdryDeptCount() { + return zdryDeptCount; + } + + public void setZdryDeptCount(String zdryDeptCount) { + this.zdryDeptCount = zdryDeptCount; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/model/KeyPerson.java b/app/src/main/java/com/police/policedatasystem/model/KeyPerson.java new file mode 100644 index 0000000..9708000 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/model/KeyPerson.java @@ -0,0 +1,86 @@ +package com.police.policedatasystem.model; + +import java.io.Serializable; + +public class KeyPerson implements Serializable { + //姓名 + private String xm; + //管控类别 + private String gklb; + //群体列表 + private String qtlb; + //责任民警姓名 + private String zrmj; + //身份证号码 + private String sfzh; + //照片base64 + private String zp; + //有效期 + private String yxq; + public String getXm() { + return xm; + } + + public void setXm(String xm) { + this.xm = xm; + } + + public String getGklb() { + return gklb; + } + + public void setGklb(String gklb) { + this.gklb = gklb; + } + + public String getQtlb() { + return qtlb; + } + + public void setQtlb(String qtlb) { + this.qtlb = qtlb; + } + + public String getZrmj() { + return zrmj; + } + + public void setZrmj(String zrmj) { + this.zrmj = zrmj; + } + + public String getSfzh() { + return sfzh; + } + + public void setSfzh(String sfzh) { + this.sfzh = sfzh; + } + + public String getZp() { + return zp; + } + + public void setZp(String zp) { + this.zp = zp; + } + + public String getYxq() { + return yxq; + } + + public void setYxq(String yxq) { + this.yxq = yxq; + } + + @Override + public String toString() { + return "KeyPerson{" + + "xm='" + xm + '\'' + + ", gklb='" + gklb + '\'' + + ", qtlb='" + qtlb + '\'' + + ", zrmj='" + zrmj + '\'' + + ", sfzh='" + sfzh + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/model/KeyPersonDetail.java b/app/src/main/java/com/police/policedatasystem/model/KeyPersonDetail.java new file mode 100644 index 0000000..67e5f3b --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/model/KeyPersonDetail.java @@ -0,0 +1,289 @@ +package com.police.policedatasystem.model; + +import java.io.Serializable; +import java.util.List; + +/** + * 重点人详情 + */ +public class KeyPersonDetail implements Serializable { + private String fwcs;//服务场所 + private String gmsfhm;//身份证号码 + private String hcdp;//火车订票信息 + private String hjdz;//户籍地址 + private String jg;//籍贯 + private String kcdp;//客车订票信息 + private String fjdp;//飞机订票信息 + private String mz;//民族 + private String xb;//性别 + private String xm;//姓名 + private String zjzs;//最近住宿 + private String zp;//照片 + private String djchphm;//机动车牌号 + private String jzdhhm;//手机号 + private String hypo;//婚姻 + private String sjgj;//手机轨迹 + private String clzhwz;//车辆最后位置 + private String bq;//标签 + + public String getBq() { + return bq; + } + + public void setBq(String bq) { + this.bq = bq; + } + + public String getClzhwz() { + return clzhwz; + } + + public void setClzhwz(String clzhwz) { + this.clzhwz = clzhwz; + } + + public String getSjgj() { + return sjgj; + } + + public String getFjdp() { + return fjdp; + } + + public void setFjdp(String fjdp) { + this.fjdp = fjdp; + } + + public void setSjgj(String sjgj) { + this.sjgj = sjgj; + } + + public String getHypo() { + return hypo; + } + + public void setHypo(String hypo) { + this.hypo = hypo; + } + + public String getJzdhhm() { + return jzdhhm; + } + + + public void setJzdhhm(String jzdhhm) { + this.jzdhhm = jzdhhm; + } + + public String getDjchphm() { + return djchphm; + } + + public void setDjchphm(String djchphm) { + this.djchphm = djchphm; + } + + public String getZp() { + return zp; + } + + public void setZp(String zp) { + this.zp = zp; + } + + private List zdryLkxxList;//姓名 + + public String getFwcs() { + return fwcs; + } + + public void setFwcs(String fwcs) { + this.fwcs = fwcs; + } + + public String getGmsfhm() { + return gmsfhm; + } + + public void setGmsfhm(String gmsfhm) { + this.gmsfhm = gmsfhm; + } + + public String getHcdp() { + return hcdp; + } + + public void setHcdp(String hcdp) { + this.hcdp = hcdp; + } + + public String getHjdz() { + return hjdz; + } + + public void setHjdz(String hjdz) { + this.hjdz = hjdz; + } + + public String getJg() { + return jg; + } + + public void setJg(String jg) { + this.jg = jg; + } + + public String getKcdp() { + return kcdp; + } + + public void setKcdp(String kcdp) { + this.kcdp = kcdp; + } + + public String getMz() { + return mz; + } + + public void setMz(String mz) { + this.mz = mz; + } + + public String getXb() { + return xb; + } + + public void setXb(String xb) { + this.xb = xb; + } + + public String getXm() { + return xm; + } + + public void setXm(String xm) { + this.xm = xm; + } + + public String getZjzs() { + return zjzs; + } + + public void setZjzs(String zjzs) { + this.zjzs = zjzs; + } + + public List getZdryLkxxList() { + return zdryLkxxList; + } + + public void setZdryLkxxList(List zdryLkxxList) { + this.zdryLkxxList = zdryLkxxList; + } + + /** + * 历史案件次数 + * + * @return + */ + public int getLsajcs() { + if (zdryLkxxList!=null){ + return zdryLkxxList.size(); + }else{ + return 0; + } + } + + public static class Lkxx implements Serializable { + private String gklb;//管控类别 + private String qtlb;//列管级别 + private String lkjz;//列控警种 + private String lksj;//列控时间 + private String lkyy;//列控原因 + private String zrdw;//责任单位 + private String zrmj;//责任民警 + private String yxq;//有效期 + private String gkjb;//管控级别 + private String zp;//照片 + + public String getQtlb() { + return qtlb; + } + + public void setQtlb(String qtlb) { + this.qtlb = qtlb; + } + + public String getZp() { + return zp; + } + + public void setZp(String zp) { + this.zp = zp; + } + + public String getGklb() { + return gklb; + } + + public void setGklb(String gklb) { + this.gklb = gklb; + } + + public String getLkjz() { + return lkjz; + } + + public void setLkjz(String lkjz) { + this.lkjz = lkjz; + } + + public String getLksj() { + return lksj; + } + + public void setLksj(String lksj) { + this.lksj = lksj; + } + + public String getLkyy() { + return lkyy; + } + + public void setLkyy(String lkyy) { + this.lkyy = lkyy; + } + + public String getZrdw() { + return zrdw; + } + + public void setZrdw(String zrdw) { + this.zrdw = zrdw; + } + + public String getZrmj() { + return zrmj; + } + + public void setZrmj(String zrmj) { + this.zrmj = zrmj; + } + + public String getYxq() { + return yxq; + } + + public void setYxq(String yxq) { + this.yxq = yxq; + } + + public String getGkjb() { + return gkjb; + } + + public void setGkjb(String gkjb) { + this.gkjb = gkjb; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/model/PoliceEmergency.java b/app/src/main/java/com/police/policedatasystem/model/PoliceEmergency.java new file mode 100644 index 0000000..abdd193 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/model/PoliceEmergency.java @@ -0,0 +1,56 @@ +package com.police.policedatasystem.model; + +import java.io.Serializable; + +public class PoliceEmergency implements Serializable { + //警情编号 + private String jcjbh; + //报警内容 + private String bjjyqk; + //报警电话 + private String bjrlxdh; + //报警时间 + private String jjsj; + //报警地址 + private String asjfsdddzmc; + + public String getJcjbh() { + return jcjbh; + } + + public void setJcjbh(String jcjbh) { + this.jcjbh = jcjbh; + } + + public String getBjjyqk() { + return bjjyqk; + } + + public void setBjjyqk(String bjjyqk) { + this.bjjyqk = bjjyqk; + } + + public String getBjrlxdh() { + return bjrlxdh; + } + + public void setBjrlxdh(String bjrlxdh) { + this.bjrlxdh = bjrlxdh; + } + + public String getJjsj() { + return jjsj; + } + + public void setJjsj(String jjsj) { + this.jjsj = jjsj; + } + + public String getAsjfsdddzmc() { + return asjfsdddzmc; + } + + public void setAsjfsdddzmc(String asjfsdddzmc) { + this.asjfsdddzmc = asjfsdddzmc; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/model/PoliceEmergencyDetail.java b/app/src/main/java/com/police/policedatasystem/model/PoliceEmergencyDetail.java new file mode 100644 index 0000000..f3d0381 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/model/PoliceEmergencyDetail.java @@ -0,0 +1,268 @@ +package com.police.policedatasystem.model; + +import java.io.Serializable; +import java.util.List; + +/** + * 警情详情 + * "asjfsdddzmc":"绿地中央公馆c6-204", + * "bjjyqk":"报警称:有人冒充民航工作人员骗取其10000元", + * "bjrlxdh":"13944800721", + * "bjrzjhm":"220104199807011310", + * "cjrxm":"肖映辉,张方贵", + * "jcjbh":"ST220120240200000046174", + * "jjsj":"20240223165000", + * "lsbjcs":"3", + * "mz":"汉族", + * "xb":"男", + * "xm":"徐瑞", + * "zp":"" + */ +public class PoliceEmergencyDetail implements Serializable { + //警情编号 + private String jcjbh; + //报警内容 + private String bjjyqk; + /*报警时间*/ + private String jjsj; + /*报警电话*/ + private String bjrlxdh; + /*报警位置*/ + private String asjfsdddzmc; + /*出境单位*/ + private String cjdwgajgjgdm; + /*出警民警*/ + private String cjrxm; + /*报警人身份证号*/ + private String bjrzjhm; + /*照片*/ + private String zp; + /*姓名*/ + private String xm; + /*性别*/ + private String xb; + /*民族*/ + private String mz; + /*年龄*/ + private String nl; + private String jg; + /*标签*/ + private String bq; + /*刑事案件前科*/ + private String xsajqk; + /*治安(行政)案件前科*/ + private String zaajqk; + /*精神病人*/ + private String jsbr; + /*残疾人*/ + private String cjr; + /*服务场所*/ + private String fwcs; + /*婚姻状况*/ + private String hyzk; + /*历史报警次数*/ + private String lsbjcs; + private String jqlb;//警情类别 + private String cllx;//处理类型 + private String cljg;//处理结果 + + public String getJqlb() { + return jqlb; + } + + public void setJqlb(String jqlb) { + this.jqlb = jqlb; + } + + public String getCllx() { + return cllx; + } + + public void setCllx(String cllx) { + this.cllx = cllx; + } + + public String getCljg() { + return cljg; + } + + public void setCljg(String cljg) { + this.cljg = cljg; + } + + public String getJcjbh() { + return jcjbh; + } + + public String getJg() { + return jg; + } + + public void setJg(String jg) { + this.jg = jg; + } + + public void setJcjbh(String jcjbh) { + this.jcjbh = jcjbh; + } + + public String getBjjyqk() { + return bjjyqk; + } + + public void setBjjyqk(String bjjyqk) { + this.bjjyqk = bjjyqk; + } + + public String getJjsj() { + return jjsj; + } + + public void setJjsj(String jjsj) { + this.jjsj = jjsj; + } + + public String getBjrlxdh() { + return bjrlxdh; + } + + public void setBjrlxdh(String bjrlxdh) { + this.bjrlxdh = bjrlxdh; + } + + public String getAsjfsdddzmc() { + return asjfsdddzmc; + } + + public void setAsjfsdddzmc(String asjfsdddzmc) { + this.asjfsdddzmc = asjfsdddzmc; + } + + public String getCjdwgajgjgdm() { + return cjdwgajgjgdm; + } + + public void setCjdwgajgjgdm(String cjdwgajgjgdm) { + this.cjdwgajgjgdm = cjdwgajgjgdm; + } + + public String getCjrxm() { + return cjrxm; + } + + public void setCjrxm(String cjrxm) { + this.cjrxm = cjrxm; + } + + public String getBjrzjhm() { + return bjrzjhm; + } + + public void setBjrzjhm(String bjrzjhm) { + this.bjrzjhm = bjrzjhm; + } + + public String getZp() { + return zp; + } + + public void setZp(String zp) { + this.zp = zp; + } + + public String getXm() { + return xm; + } + + public void setXm(String xm) { + this.xm = xm; + } + + public String getXb() { + return xb; + } + + public void setXb(String xb) { + this.xb = xb; + } + + public String getMz() { + return mz; + } + + public void setMz(String mz) { + this.mz = mz; + } + + public String getNl() { + return nl; + } + + public void setNl(String nl) { + this.nl = nl; + } + + public String getBq() { + return bq; + } + + public void setBq(String bq) { + this.bq = bq; + } + + public String getXsajqk() { + return xsajqk; + } + + public void setXsajqk(String xsajqk) { + this.xsajqk = xsajqk; + } + + public String getZaajqk() { + return zaajqk; + } + + public void setZaajqk(String zaajqk) { + this.zaajqk = zaajqk; + } + + public String getJsbr() { + return jsbr; + } + + public void setJsbr(String jsbr) { + this.jsbr = jsbr; + } + + public String getCjr() { + return cjr; + } + + public void setCjr(String cjr) { + this.cjr = cjr; + } + + public String getFwcs() { + return fwcs; + } + + public void setFwcs(String fwcs) { + this.fwcs = fwcs; + } + + public String getHyzk() { + return hyzk; + } + + public void setHyzk(String hyzk) { + this.hyzk = hyzk; + } + + public String getLsbjcs() { + return lsbjcs; + } + + public void setLsbjcs(String lsbjcs) { + this.lsbjcs = lsbjcs; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/model/ResourceList.java b/app/src/main/java/com/police/policedatasystem/model/ResourceList.java new file mode 100644 index 0000000..cc694e0 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/model/ResourceList.java @@ -0,0 +1,42 @@ +package com.police.policedatasystem.model; + +import java.io.Serializable; + +public class ResourceList implements Serializable { + private String resourceRegionalismCode; + private String resourceAddress; + private String resourceId; + private String resourceServiceType; + + public String getResourceRegionalismCode() { + return resourceRegionalismCode; + } + + public void setResourceRegionalismCode(String resourceRegionalismCode) { + this.resourceRegionalismCode = resourceRegionalismCode; + } + + public String getResourceAddress() { + return resourceAddress; + } + + public void setResourceAddress(String resourceAddress) { + this.resourceAddress = resourceAddress; + } + + public String getResourceId() { + return resourceId; + } + + public void setResourceId(String resourceId) { + this.resourceId = resourceId; + } + + public String getResourceServiceType() { + return resourceServiceType; + } + + public void setResourceServiceType(String resourceServiceType) { + this.resourceServiceType = resourceServiceType; + } +} diff --git a/app/src/main/java/com/police/policedatasystem/model/UserCredential.java b/app/src/main/java/com/police/policedatasystem/model/UserCredential.java new file mode 100644 index 0000000..339d54c --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/model/UserCredential.java @@ -0,0 +1,174 @@ +package com.police.policedatasystem.model; + +import java.io.Serializable; + +/** + * { + * "credential":{ + * "head":{ + * "credType":"1", + * "duration":{ + * "endTime":"1709387466556", + * "startTime":"1709380266556" + * }, + * "token":{ + * "orgId":"220000000000", + * "tokenId":"ff8080818bc29187018dff00ea3d33fb" + * }, + * "version":"1.0" + * }, + * "load":{ + * "userInfo":{ + * "jh":"106686", + * "orgId":"220100410000", + * "sfzh":"220105198602152031", + * "userId":"162add958ea344f68d07b6ad2c4b17a7", + * "xm":"路瑶" + * } + * }, + * "serverSign":{ + * "alg":"SM3+SM2", + * "signature":"2WIjCJ/+94XmtIei2+/8eV40dxfvQGqV4ws7WDA5iNPc//zeZTFNewibqa8OSKprWq2P6mnWHMkVPYP+Qdl7Huc0qHJMVFUovF+mqtO5pSxrngem5kXmVK9v1NV7OMurPpa1FiQc1uU0A4Zae4ZrpynM2+qEck/D8KSvLvsKkCQ\u003d", + * "sn":"b11000000000bdc", + * "url":"http://192.168.24.108:8080" + * } + * } + * } + */ +public class UserCredential implements Serializable { + private Credential credential; + + public Credential getCredential() { + return credential; + } + + public void setCredential(Credential credential) { + this.credential = credential; + } + + public static class Credential implements Serializable { + private Head head; + private Load load; + private ServerSign serverSign; + + public Head getHead() { + return head; + } + + public void setHead(Head head) { + this.head = head; + } + + public Load getLoad() { + return load; + } + + public void setLoad(Load load) { + this.load = load; + } + + public ServerSign getServerSign() { + return serverSign; + } + + public void setServerSign(ServerSign serverSign) { + this.serverSign = serverSign; + } + } + + public static class Head implements Serializable{ + private Head head; + private Load load; + private ServerSign serverSign; + + public Head getHead() { + return head; + } + + public void setHead(Head head) { + this.head = head; + } + + public Load getLoad() { + return load; + } + + public void setLoad(Load load) { + this.load = load; + } + + public ServerSign getServerSign() { + return serverSign; + } + + public void setServerSign(ServerSign serverSign) { + this.serverSign = serverSign; + } + } + + public static class Load implements Serializable { + private UserInfo userInfo; + + public UserInfo getUserInfo() { + return userInfo; + } + + public void setUserInfo(UserInfo userInfo) { + this.userInfo = userInfo; + } + } + + public static class ServerSign { + private Head head; + private Load load; + private ServerSign serverSign; + } + + public static class UserInfo implements Serializable { + String jh;//"jh":"106686", + String orgId;//"orgId":"220100410000", + String sfzh;//"sfzh":"220105198602152031", + String userId;//"userId":"162add958ea344f68d07b6ad2c4b17a7", + String xm;//"xm":"路瑶" + + public String getJh() { + return jh; + } + + public void setJh(String jh) { + this.jh = jh; + } + + public String getOrgId() { + return orgId; + } + + public void setOrgId(String orgId) { + this.orgId = orgId; + } + + public String getSfzh() { + return sfzh; + } + + public void setSfzh(String sfzh) { + this.sfzh = sfzh; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getXm() { + return xm; + } + + public void setXm(String xm) { + this.xm = xm; + } + } +} diff --git a/app/src/main/java/com/police/policedatasystem/util/Constants.java b/app/src/main/java/com/police/policedatasystem/util/Constants.java new file mode 100644 index 0000000..49ac0e8 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/util/Constants.java @@ -0,0 +1,63 @@ +package com.police.policedatasystem.util; + +import com.police.policedatasystem.model.ResourceList; + +import java.util.HashMap; + +public final class Constants { + /** + * 根据警员编号重点人员信息列表 + */ + public static final String KEY_PERSON_ID = "220000000000-3-0100-103cab8edd784a688ac3c41476454a3a"; + /** + * 根据组织机构查询辖区重点人 + */ + public static final String ORG_KEY_PERSON_ID = "220000000000-3-0100-2faa9acfe614420c8a0c74dbf257d963"; + /** + * 重点人员信息详情 + */ + public static final String KEY_PERSON_DETAIL_ID = "220000000000-3-0100-e589d230e71942a3b87f2e050fbd2058"; + /** + * 警情列表 + */ + public static final String POLICE_EMERGENCY_ID = "220000000000-3-0100-013e30a83e854b1badc23dd31e7dcfec"; + /** + * 警情详情 + */ + public static final String POLICE_EMERGENCY_DETAIL_ID = "220000000000-3-0100-25a416bd99ef4cd19a523715b9612fa1"; + /** + * 重点人消息数量统计 + */ + public static final String KEY_PERSON_MESSAGE_COUNT_ID = "220000000000-3-0100-d29a1ec21b9e44dab6e69a26598b8b8e"; + /** + * 重点人员信息详情 + */ + public static final String ORG_ID = "220000000000"; + /** + * 重点人员信息id + */ + public static final String APP_ID = "220000000000-3-1-71d6313523574202bb1f9984b6d95254"; + public static String APP_CREDENTIAL = ""; + public static String USER_CREDENTIAL = ""; + /** + * 当前用户警员编号 + */ + public static String USER_ID = "100307"; + /** + * 当前用户身份证号 + */ + public static String SFZH = "100307"; + + /** + * 当前用户警员组织代码 + */ + public static String USER_ORG_ID = "22018421000";//22018421000//220106290000 + /** + * 寻址后得到的数据-接口列表 + */ + public static final HashMap resourceListsMap = new HashMap<>(); + /** + * 请求分页数据数量 + */ + public static int PAGE_SIZE = 10; +} \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/util/ThirdAppInfo.java b/app/src/main/java/com/police/policedatasystem/util/ThirdAppInfo.java new file mode 100644 index 0000000..11313ac --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/util/ThirdAppInfo.java @@ -0,0 +1,65 @@ +package com.police.policedatasystem.util; + +import java.io.Serializable; + +public class ThirdAppInfo implements Serializable { + private String messageId; + + private String packageName; + + private String appId; + + private String orgId; + + private String networkAreaCode; + + private String version; + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public String getMessageId() { + return messageId; + } + + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + public String getAppId() { + return appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public String getOrgId() { + return orgId; + } + + public void setOrgId(String orgId) { + this.orgId = orgId; + } + + public String getNetworkAreaCode() { + return networkAreaCode; + } + + public void setNetworkAreaCode(String networkAreaCode) { + this.networkAreaCode = networkAreaCode; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} diff --git a/app/src/main/java/com/police/policedatasystem/util/UaCredentialApi.java b/app/src/main/java/com/police/policedatasystem/util/UaCredentialApi.java new file mode 100644 index 0000000..444d478 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/util/UaCredentialApi.java @@ -0,0 +1,305 @@ +package com.police.policedatasystem.util; + +import android.app.Activity; +import android.content.ActivityNotFoundException; +import android.content.BroadcastReceiver; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.content.pm.ProviderInfo; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.text.TextUtils; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class UaCredentialApi { + + + /**********************************************以下是统一认证登录时使用的参数字段常量定义*************************************************************/ + + /** + * 统一认证登录接口(统一认证客户端(UAAC)提供) + */ + public static final String PROVIDER_URI_GET_CREDENTIAL = "content://com.ydjw.ua.getCredential"; + + public static final String PARAMS_KEY_UA_VERSION_VALUE = "1"; + + public static final String PARAMS_KEY_UA_MESSAGE_ID = "messageId"; + + public static final String PARAMS_KEY_UA_VERSION = "version"; + + public static final String PARAMS_KEY_UA_APP_ID = "appId"; + + public static final String PARAMS_KEY_UA_ORG_ID = "orgId"; + + public static final String PARAMS_KEY_UA_NETWORK_AREA_CODE = "networkAreaCode"; + + public static final String PARAMS_KEY_UA_PACKAGE_NAME = "packageName"; + + public static final String PARAMS_KEY_UA_RET_CODE = "resultCode"; + + public static final String PARAMS_KEY_UA_RET_MESSAGE = "message"; + + public static final String PARAMS_KEY_THIRD_APP_INFO = "third_app_info"; + + public static final int PARAMS_KEY_UA_RET_SUCCESS = 0; + + public static final int PARAMS_KEY_UA_RET_ERROR_PARAMS = -3; + + public static final int PARAMS_KEY_UA_RET_ERROR_NOT_EXISTS = -5; + + public static final int CREDENTIAL_CLIENT_NOT_INSTALLED = -7; + + public static final int PARAMS_KEY_UA_RET_ERROR_OTHER = -99; + + public static final String PARAMS_KEY_UA_APP_CREDENTIAL = "appCredential"; + + public static final String PARAMS_KEY_UA_USER_CREDENTIAL = "userCredential"; + + public static final String ACTION_SUFFIX_UA_LOGIN = ".ACTION_LOGIN"; + + public static final String ACTION_UA_LOGOUT = "com.ydjw.ua.ACTION_LOGOUT"; + + /**********************************************以下是统一认证登录时使用的参数字段常量定义*************************************************************/ + + private boolean notExists = false; + + public CredentialReqCallBack credentialReqCallBack; + + private String mMessageId; + + private Context mContext; + private String version = UaCredentialApi.PARAMS_KEY_UA_VERSION_VALUE; + private String appId; + private String orgId; + private String networkAreaCode; + + + private static Map packageActivityMap = new HashMap<>(); + + /** + * 统一认证应用包名(历史原因,统一认证单点登录功能存在多个客户端) + */ + private static String uaacPackageName; + + /** + * 统一认证启动Activity类名 + */ + private static String uaacLoginActivityName; + + static { + //新版统一认证 + packageActivityMap.put("com.xdja.uaac", "com.xdja.uaac.ui.InitActivity"); + //旧版统一认证 + packageActivityMap.put("com.xdja.unifyauthorize", "com.xdja.unifyauthorize.activity.LoginActivity"); + //安全接入融合版 + packageActivityMap.put("com.xdja.safeclient", "com.xdja.safeclient.frame.SplashActivity"); + //警信内部集成的旧版统一认证 + packageActivityMap.put("com.xdja.jxclient", "com.xdja.unifyauthorize.activity.LoginActivity"); + } + + public UaCredentialApi(Builder builder) { + this.mContext = builder.mContext; + this.version = builder.version; + this.appId = builder.appId; + this.orgId = builder.orgId; + this.networkAreaCode = builder.networkAreaCode; + } + + public static class Builder { + protected Context mContext; + protected String version; + protected String appId; + protected String orgId; + protected String networkAreaCode; + + public Builder(Context context) { + this.mContext = context; + } + + public Builder setAppId(String appId) { + this.appId = appId; + return this; + } + + public Builder setVersion(String version) { + this.version = version; + return this; + } + + public Builder setOrgId(String orgId) { + this.orgId = orgId; + return this; + } + + public Builder setNetworkAreaCode(String networkAreaCode) { + this.networkAreaCode = networkAreaCode; + return this; + } + + public UaCredentialApi build() { + return new UaCredentialApi(this); + } + } + + public void reqCredential(CredentialReqCallBack reqCallBack) { + this.credentialReqCallBack = reqCallBack; + + IntentFilter intentFilter = new IntentFilter(); + String pkgName = mContext.getPackageName(); + /**添加登录成功事件监听 + * 当第一次登录,调用【IF-UA-SDK-01】接口可能返回"票据不存在",此时需要注册监听此事件, + * 当登录成功后,接收到此事件即可重新调用【IF-UA-SDK-01】获取相关票据 + * */ + intentFilter.addAction(pkgName + ACTION_SUFFIX_UA_LOGIN); + + /**增加登出事件监听 + * 当UA主动账户退出时会发送该事件,此时已经登录应用可以根据自身业务实施退出 + * */ + intentFilter.addAction(pkgName + ACTION_UA_LOGOUT); + mContext.registerReceiver(uaLoginInReceiver, intentFilter); + loginUaForCredential(mContext); + } + + public void release() { + notExists = false; + if (uaLoginInReceiver == null) { + return; + } + mContext.unregisterReceiver(uaLoginInReceiver); + } + + private BroadcastReceiver uaLoginInReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (TextUtils.isEmpty(action)) { + return; + } + + if (action.contains(ACTION_SUFFIX_UA_LOGIN) && notExists) { + loginUaForCredential(mContext); + } + } + }; + + /** + * 【步骤1:IF-UA-SDK-01】获取凭证信息 + *
调用此接口获取用户凭证和应用凭证
+ *
如用户已登录 UA客户端,则直接向应用返回凭证信息
+ *
如未登录,待登录完成后将通过广播的形式向应用发送用户登录成功广播,此时可以监听广播重新获取凭证信息
+ */ + private void loginUaForCredential(Context context) { + + if (!isCredentialProviderExist(context)) { + credentialReqCallBack.onCredentialCallBack(CREDENTIAL_CLIENT_NOT_INSTALLED, "未找到UA客户端", "", ""); + return; + } + + notExists = false; + String messageId = UUID.randomUUID().toString().replace("-",""); + mMessageId = messageId; + Uri uri = Uri.parse(PROVIDER_URI_GET_CREDENTIAL); + ContentResolver resolver = context.getContentResolver(); + Bundle params = new Bundle(); + + String packageName = context.getPackageName(); + params.putString(PARAMS_KEY_UA_MESSAGE_ID, messageId); + params.putString(PARAMS_KEY_UA_VERSION, version); + params.putString(PARAMS_KEY_UA_APP_ID, appId); + params.putString(PARAMS_KEY_UA_ORG_ID, orgId); + params.putString(PARAMS_KEY_UA_NETWORK_AREA_CODE, networkAreaCode); + params.putString(PARAMS_KEY_UA_PACKAGE_NAME, packageName); + + try { + Bundle result = resolver.call(uri, "", null, params); + if (result == null) { + credentialReqCallBack.onCredentialCallBack(PARAMS_KEY_UA_RET_ERROR_OTHER, "获取应用凭证失败,bundle为空", "", ""); + return; + } + String messageIdRet = result.getString(PARAMS_KEY_UA_MESSAGE_ID); + if (!mMessageId.equals(messageIdRet)) { + credentialReqCallBack.onCredentialCallBack(PARAMS_KEY_UA_RET_ERROR_OTHER, "获取应用凭证失败,messageId不对应", "", ""); + return; + } + + receiveCredential(result); + } catch (ActivityNotFoundException activityNotFoundException) { + activityNotFoundException.printStackTrace(); + receiveCredentialError(null, activityNotFoundException); + } catch (Exception e) { + e.printStackTrace(); + receiveCredentialError(null, e); + } + } + + private void receiveCredentialError(Bundle result, Exception e) { + credentialReqCallBack.onCredentialCallBack(PARAMS_KEY_UA_RET_ERROR_OTHER, "调用UA客户端获取凭证接口异常:" + (e == null ? "" : e.getMessage()), "", ""); + } + + /** + * 【步骤I:IF-UA-SDK-01】处理获取凭证结果 + * + * @param result + */ + private void receiveCredential(Bundle result) { + + int resultCode = result.getInt(PARAMS_KEY_UA_RET_CODE); + if (PARAMS_KEY_UA_RET_SUCCESS == resultCode) { + String appCredential = result.getString(PARAMS_KEY_UA_APP_CREDENTIAL); + String userCredential = result.getString(PARAMS_KEY_UA_USER_CREDENTIAL); + credentialReqCallBack.onCredentialCallBack(resultCode, "", userCredential, appCredential); + return; + } + + if (PARAMS_KEY_UA_RET_ERROR_NOT_EXISTS == resultCode) { + notExists = true; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + Intent intent = new Intent(); + intent.setClassName(uaacPackageName, uaacLoginActivityName); + final ThirdAppInfo thirdAppInfo = new ThirdAppInfo(); + thirdAppInfo.setMessageId(result.getString(PARAMS_KEY_UA_MESSAGE_ID)); + thirdAppInfo.setPackageName(mContext.getPackageName()); + thirdAppInfo.setAppId(appId); + thirdAppInfo.setOrgId(orgId); + thirdAppInfo.setNetworkAreaCode(networkAreaCode); + thirdAppInfo.setVersion(version); + intent.putExtra(PARAMS_KEY_THIRD_APP_INFO, thirdAppInfo); + if (!(mContext instanceof Activity)) { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + } + mContext.startActivity(intent); + } + return; + } + + String message = result.getString(PARAMS_KEY_UA_RET_MESSAGE); + credentialReqCallBack.onCredentialCallBack(resultCode, message, "", ""); + } + + /** + * 判断凭证Provider是否存在,如果存在获取Provider所在应用的包名 + */ + private static boolean isCredentialProviderExist(Context context) { + PackageManager packageManager = context.getPackageManager(); + ProviderInfo providerInfo = packageManager.resolveContentProvider(Uri.parse(PROVIDER_URI_GET_CREDENTIAL).getAuthority(), PackageManager.GET_META_DATA); + if (providerInfo == null) { + return false; + } else { + uaacPackageName = providerInfo.applicationInfo.packageName; + uaacLoginActivityName = packageActivityMap.get(uaacPackageName); + return true; + } + } + + public interface CredentialReqCallBack { + void onCredentialCallBack(int resultCode, String message, String userCredential, String appCredential); + } + +} diff --git a/app/src/main/java/com/police/policedatasystem/util/UiUtils.java b/app/src/main/java/com/police/policedatasystem/util/UiUtils.java new file mode 100644 index 0000000..bf05fca --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/util/UiUtils.java @@ -0,0 +1,78 @@ +package com.police.policedatasystem.util; + +import android.util.Base64; +import android.widget.Toast; + +import com.police.policedatasystem.MyApplication; + +import java.util.UUID; + +public class UiUtils { + /** + * 将dp值转换为px值,保证尺寸大小不变 + * + * @param dpValue dp值 + * @return 转换后的px值 + */ + public static int dp2Px(int dpValue) { + final float scale = MyApplication.getInstance().getResources().getDisplayMetrics().density; + return Math.round((float) dpValue * scale); + } + public static String uuid() { + return UUID.randomUUID().toString(); + } + + public static void toast(String str) { + MyApplication.getInstance().getHandler().post(() -> Toast.makeText(MyApplication.getInstance(), str, Toast.LENGTH_LONG).show()); + } + + public static boolean isEmpty(String str) { + if (str == null) { + return true; + } + return str.isEmpty(); + } + + public static boolean isNotEmpty(String str) { + if (str == null) { + return false; + } + return !str.isEmpty(); + } + public static void ui(){ + MyApplication.getHandler().post(new Runnable() { + @Override + public void run() { + + } + }); + } + + + public static byte[] base64ToBytes(String base64Str) { + return Base64.decode(base64Str, Base64.DEFAULT); + } + public static String formatTime(String str) { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + if (UiUtils.isEmpty(str)) return ""; + if (str.contains("-")) { + return str; + } + if (str.length() == 8) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(str.substring(0, 4)).append("-" + str.substring(4, 6)).append("-" + str.substring(6, 8)); + return stringBuilder.toString(); + } + if (str.length() > 8) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(str.substring(0, 4)) + .append("-" + str.substring(4, 6)) + .append("-" + str.substring(6, 8)) + .append(" " + str.substring(8, 10)) + .append(":" + str.substring(10, 12)); + return stringBuilder.toString(); + } + } + return ""; + } +} diff --git a/app/src/main/java/com/police/policedatasystem/viewmodel/DataViewModel.java b/app/src/main/java/com/police/policedatasystem/viewmodel/DataViewModel.java new file mode 100644 index 0000000..e712b92 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/viewmodel/DataViewModel.java @@ -0,0 +1,360 @@ +package com.police.policedatasystem.viewmodel; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; +import com.police.policedatasystem.activity.KeyPersonDetailActivity; +import com.police.policedatasystem.activity.PoliceEmergencyDetailActivity; +import com.police.policedatasystem.fragment.DataFragment; +import com.police.policedatasystem.http.CustomCallBack; +import com.police.policedatasystem.http.requestparams.GetKeyPersonListParams; +import com.police.policedatasystem.http.requestparams.GetOrgKeyPersonListParams; +import com.police.policedatasystem.http.requestparams.GetPoliceEmergencyListParams; +import com.police.policedatasystem.indexActivity; +import com.police.policedatasystem.model.DataCount; +import com.police.policedatasystem.model.KeyPerson; +import com.police.policedatasystem.model.KeyPersonDetail; +import com.police.policedatasystem.model.PoliceEmergency; +import com.police.policedatasystem.model.PoliceEmergencyDetail; +import com.police.policedatasystem.util.Constants; +import com.police.policedatasystem.util.UiUtils; + +import java.util.List; + +import okhttp3.Call; + +public class DataViewModel { + private final DataFragment fragment; + public int pageNum = 1; + public indexActivity activity; + + public DataViewModel(DataFragment fragment, indexActivity activity) { + this.fragment = fragment; + this.activity = activity; + } + + public void keyPersonInit() { + fragment.loadingShow(); + pageNum = 1; + fragment.personList.clear(); + //加载数据 + GetKeyPersonListParams params = new GetKeyPersonListParams(); + params.setPageNum(pageNum + ""); + if (fragment.filterType == 0) { + params.setXm(fragment.binding.etInput.getText().toString()); + } else { + params.setSfzh(fragment.binding.etInput.getText().toString()); + } + activity.requestClient.getKeyPerson(params, new CustomCallBack>() { + @Override + public void onError(@NonNull Call call, @NonNull Exception e) { + UiUtils.toast(e.getMessage()); + fragment.loadingNone(); + } + + @Override + public void onSuccess(List value) { + fragment.loadingNone(); + if (value != null) { + fragment.personList.addAll(value); + } + fragment.adapter.notifyDataSetChanged(); + } + }); + } + + public void orgKeyPersonInit() { + fragment.loadingShow(); + pageNum = 1; + fragment.personList.clear(); + //加载数据 + GetOrgKeyPersonListParams params = new GetOrgKeyPersonListParams(); + params.setPageNum(pageNum + ""); + if (fragment.filterType == 0) { + params.setXm(fragment.binding.etInput.getText().toString()); + } else { + params.setSfzh(fragment.binding.etInput.getText().toString()); + } + activity.requestClient.getOrgKeyPerson(params, new CustomCallBack>() { + @Override + public void onError(@NonNull Call call, @NonNull Exception e) { + fragment.loadingNone(); + UiUtils.toast(e.getMessage()); + } + + @Override + public void onSuccess(List value) { + fragment.loadingNone(); + if (value != null) { + fragment.personList.addAll(value); + } + fragment.adapter.notifyDataSetChanged(); + } + }); + } + + public void keyPersonLoadMore() { + fragment.loadingShow(); + //加载数据 + GetKeyPersonListParams params = new GetKeyPersonListParams(); + pageNum++; + params.setPageNum(pageNum + ""); + activity.requestClient.getKeyPerson(params, new CustomCallBack>() { + @Override + public void onError(@NonNull Call call, @NonNull Exception e) { + fragment.loadingNone(); + fragment.binding.refreshLayout.finishLoadMore(); + UiUtils.toast(e.getMessage()); + } + + @Override + public void onSuccess(List value) { + fragment.loadingNone(); + if (value == null || value.size() < Constants.PAGE_SIZE) { + fragment.binding.refreshLayout.setNoMoreData(true); + } + if (value != null) { + fragment.personList.addAll(value); + } + fragment.adapter.notifyDataSetChanged(); + fragment.binding.refreshLayout.finishLoadMore(); + } + }); + } + + public void keyPersonRefresh() { + fragment.loadingShow(); + fragment.personList.clear(); + pageNum = 1; + //加载数据 + GetKeyPersonListParams params = new GetKeyPersonListParams(); + params.setPageNum(pageNum + ""); + activity.requestClient.getKeyPerson(params, new CustomCallBack>() { + @Override + public void onError(@NonNull Call call, @NonNull Exception e) { + fragment.loadingNone(); + fragment.binding.refreshLayout.finishRefresh(); + UiUtils.toast(e.getMessage()); + } + + @Override + public void onSuccess(List value) { + fragment.loadingNone(); + if (value != null) { + fragment.personList.addAll(value); + } + fragment.adapter.notifyDataSetChanged(); + fragment.binding.refreshLayout.finishRefresh(); + } + }); + } + + public void orgKeyPersonLoadMore() { + fragment.loadingShow(); + //加载数据 + GetOrgKeyPersonListParams params = new GetOrgKeyPersonListParams(); + pageNum++; + params.setPageNum(pageNum + ""); + activity.requestClient.getOrgKeyPerson(params, new CustomCallBack>() { + @Override + public void onError(@NonNull Call call, @NonNull Exception e) { + fragment.loadingNone(); + fragment.binding.refreshLayout.finishLoadMore(); + UiUtils.toast(e.getMessage()); + } + + @Override + public void onSuccess(List value) { + fragment.loadingNone(); + if (value == null || value.size() < Constants.PAGE_SIZE) { + fragment.binding.refreshLayout.setNoMoreData(true); + } + if (value != null) { + fragment.personList.addAll(value); + } + fragment.adapter.notifyDataSetChanged(); + fragment.binding.refreshLayout.finishLoadMore(); + } + }); + } + + public void orgKeyPersonRefresh() { + fragment.loadingShow(); + fragment.personList.clear(); + pageNum = 1; + //加载数据 + GetOrgKeyPersonListParams params = new GetOrgKeyPersonListParams(); + params.setPageNum(pageNum + ""); + activity.requestClient.getOrgKeyPerson(params, new CustomCallBack>() { + @Override + public void onError(@NonNull Call call, @NonNull Exception e) { + fragment.loadingNone(); + fragment.binding.refreshLayout.finishRefresh(); + UiUtils.toast(e.getMessage()); + } + + @Override + public void onSuccess(List value) { + fragment.loadingNone(); + if (value != null) { + fragment.personList.addAll(value); + } + fragment.adapter.notifyDataSetChanged(); + fragment.binding.refreshLayout.finishRefresh(); + } + }); + } + + public void keyPersonDetail(String sfzh) { + fragment.loadingShow(); + activity.requestClient.keyPersonDetail(sfzh, new CustomCallBack() { + @Override + public void onError(@NonNull Call call, @NonNull Exception e) { + fragment.loadingNone(); + UiUtils.toast(e.getMessage()); + } + + @Override + public void onSuccess(KeyPersonDetail value) { + fragment.loadingNone(); + KeyPersonDetailActivity.startAction(activity, new Gson().toJson(value)); + } + }); + } + + /** + * 警情数据初始化 + */ + public void policeEmergencyInit() { + fragment.loadingShow(); + pageNum = 1; + fragment.policeList.clear(); + //加载数据 + GetPoliceEmergencyListParams params = new GetPoliceEmergencyListParams(); + params.setPageNum(pageNum + ""); + if (fragment.filterType == 0) { + params.setJcjbh(fragment.binding.etInput.getText().toString()); + } else if (fragment.filterType == 1) { + params.setBjjyqk(fragment.binding.etInput.getText().toString()); + } else { + params.setBjrlxdh(fragment.binding.etInput.getText().toString()); + } + activity.requestClient.getPoliceEmergency(params, new CustomCallBack>() { + @Override + public void onError(@NonNull Call call, @NonNull Exception e) { + UiUtils.toast(e.getMessage()); + fragment.loadingNone(); + } + + @Override + public void onSuccess(List value) { + fragment.loadingNone(); + if (value != null) { + fragment.policeList.addAll(value); + } + fragment.adapter.notifyDataSetChanged(); + } + }); + } + + public void policeEmergencyRefresh() { + fragment.loadingShow(); + pageNum = 1; + fragment.policeList.clear(); + //加载数据 + GetPoliceEmergencyListParams params = new GetPoliceEmergencyListParams(); + params.setPageNum(pageNum + ""); + if (fragment.filterType == 0) { + params.setJcjbh(fragment.binding.etInput.getText().toString()); + } else if (fragment.filterType == 1) { + params.setBjjyqk(fragment.binding.etInput.getText().toString()); + } else { + params.setBjrlxdh(fragment.binding.etInput.getText().toString()); + } + activity.requestClient.getPoliceEmergency(params, new CustomCallBack>() { + @Override + public void onError(@NonNull Call call, @NonNull Exception e) { + fragment.binding.refreshLayout.finishRefresh(); + UiUtils.toast(e.getMessage()); + fragment.loadingNone(); + } + + @Override + public void onSuccess(List value) { + fragment.binding.refreshLayout.finishRefresh(); + fragment.loadingNone(); + if (value != null) { + fragment.policeList.addAll(value); + } + fragment.adapter.notifyDataSetChanged(); + } + }); + } + + public void policeEmergencyLoadMore() { + fragment.loadingShow(); + //加载数据 + GetPoliceEmergencyListParams params = new GetPoliceEmergencyListParams(); + pageNum++; + params.setPageNum(pageNum + ""); + activity.requestClient.getPoliceEmergency(params, new CustomCallBack>() { + @Override + public void onError(@NonNull Call call, @NonNull Exception e) { + fragment.loadingNone(); + fragment.binding.refreshLayout.finishLoadMore(); + UiUtils.toast(e.getMessage()); + } + + @Override + public void onSuccess(List value) { + fragment.loadingNone(); + if (value == null || value.size() < Constants.PAGE_SIZE) { + fragment.binding.refreshLayout.setNoMoreData(true); + } + if (value != null) { + fragment.policeList.addAll(value); + } + fragment.adapter.notifyDataSetChanged(); + fragment.binding.refreshLayout.finishLoadMore(); + } + }); + } + + public void policeEmergencyDetail(String jcjbh) { + fragment.loadingShow(); + activity.requestClient.getPoliceEmergencyDetail(jcjbh, new CustomCallBack() { + @Override + public void onError(@NonNull Call call, @NonNull Exception e) { + fragment.loadingNone(); + UiUtils.toast(e.getMessage()); + } + + @Override + public void onSuccess(PoliceEmergencyDetail value) { + fragment.loadingNone(); + PoliceEmergencyDetailActivity.startAction(activity, new Gson().toJson(value)); + } + }); + } + + public void getKeyPersonMessageCount() { + fragment.loadingShow(); + activity.requestClient.getKeyPersonMessageCount( new CustomCallBack() { + @Override + public void onError(@NonNull Call call, @NonNull Exception e) { + fragment.loadingNone(); + UiUtils.toast(e.getMessage()); + } + + @Override + public void onSuccess(DataCount value) { + fragment.loadingNone(); + fragment.binding.tvKeyPersonCount.setText(value.getZdryCount()); + fragment.binding.tvPoliceEmergencyCount.setText(value.getJqCount()); + fragment.binding.tvCaseDetailsCount.setText(value.getAqCount()); + fragment.binding.tvKeyPersonTabCount.setText(value.getZdryCount()); + fragment.binding.tvAreaKeyTabCount.setText(value.getZdryDeptCount()); + } + }); + } +} diff --git a/app/src/main/java/com/police/policedatasystem/viewmodel/IndexViewModel.java b/app/src/main/java/com/police/policedatasystem/viewmodel/IndexViewModel.java new file mode 100644 index 0000000..ea4c2c2 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/viewmodel/IndexViewModel.java @@ -0,0 +1,13 @@ +package com.police.policedatasystem.viewmodel; + +import com.police.policedatasystem.indexActivity; + +public class IndexViewModel { + private final indexActivity activity; + public int pageNum = 1; + + public IndexViewModel(indexActivity activity) { + this.activity = activity; + } + +} diff --git a/app/src/main/java/com/police/policedatasystem/widget/WaterMarkBg.java b/app/src/main/java/com/police/policedatasystem/widget/WaterMarkBg.java new file mode 100644 index 0000000..91c24f5 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/widget/WaterMarkBg.java @@ -0,0 +1,88 @@ +package com.police.policedatasystem.widget; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.drawable.Drawable; + +import androidx.annotation.IntRange; +import androidx.annotation.Nullable; + +import java.util.List; + +public class WaterMarkBg extends Drawable { + private Paint paint = new Paint(); + private List labels; + private Context context; + private int degress;//角度 + private int fontSize;//字体大小 单位sp + + /** + * 初始化构造 + * + * @param context 上下文 + * @param labels 水印文字列表 多行显示支持 + * @param degress 水印角度 + * @param fontSize 水印文字大小 + */ + public WaterMarkBg(Context context, List labels, int degress, int fontSize) { + this.labels = labels; + this.context = context; + this.degress = degress; + this.fontSize = fontSize; + } + + @Override + public void draw(@Nullable Canvas canvas) { + + + int width = getBounds().right; + int height = getBounds().bottom; + + canvas.drawColor(Color.parseColor("#40F3F5F9")); + paint.setColor(Color.parseColor("#50AEAEAE")); + + paint.setAntiAlias(true); + paint.setTextSize(sp2px(context, fontSize)); + canvas.save(); + canvas.rotate(degress); + float textWidth = paint.measureText(labels.get(0)); + int index = 0; + for (int positionY = height / 10; positionY <= height; positionY += height / 10 + 80) { + float fromX = -width + (index++ % 2) * textWidth; + for (float positionX = fromX; positionX < width; positionX += textWidth * 2) { + int spacing = 0;//间距 + for (String label : labels) { + canvas.drawText(label, positionX, positionY + spacing, paint); + spacing = spacing + 50; + } + + } + } + canvas.restore(); + } + + @Override + public void setAlpha(@IntRange(from = 0, to = 255) int alpha) { + + } + + @Override + public void setColorFilter(@Nullable ColorFilter colorFilter) { + + } + + @Override + public int getOpacity() { + return PixelFormat.UNKNOWN; + } + + + public static int sp2px(Context context, float spValue) { + final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; + return (int) (spValue * fontScale + 0.5f); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/widget/WaterMarkInfo.java b/app/src/main/java/com/police/policedatasystem/widget/WaterMarkInfo.java new file mode 100644 index 0000000..bbc9e73 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/widget/WaterMarkInfo.java @@ -0,0 +1,208 @@ +package com.police.policedatasystem.widget; + +import android.graphics.Color; +import android.graphics.Paint; + +/** + * @author Leon (wshk729@163.com) + * @date 2018/8/24 + *

+ */ +public class WaterMarkInfo { + + private int mDegrees; + private int mTextColor; + private int mTextSize; + private boolean mTextBold; + private int mDx; + private int mDy; + private Paint.Align mAlign; + + private WaterMarkInfo(int degrees, int textColor, int textSize, boolean textBold, int dx, int dy, Paint.Align align) { + mDegrees = degrees; + mTextColor = textColor; + mTextSize = textSize; + mTextBold = textBold; + mDx = dx; + mDy = dy; + mAlign = align; + } + + public int getDegrees() { + return mDegrees; + } + + public int getTextColor() { + return mTextColor; + } + + public int getTextSize() { + return mTextSize; + } + + public int getDx() { + return mDx; + } + + public int getDy() { + return mDy; + } + + public Paint.Align getAlign() { + return mAlign; + } + + public int getAlignInt() { + switch (mAlign) { + case LEFT: + return 0; + case RIGHT: + return 2; + default: + return 1; + } + } + + public boolean isTextBold() { + return mTextBold; + } + + void setDegrees(int degrees) { + mDegrees = degrees; + } + + void setTextColor(int textColor) { + mTextColor = textColor; + } + + void setTextSize(int textSize) { + mTextSize = textSize; + } + + void setTextBold(boolean textBold) { + mTextBold = textBold; + } + + void setDx(int dx) { + mDx = dx; + } + + void setDy(int dy) { + mDy = dy; + } + + void setAlign(Paint.Align align) { + this.mAlign = align; + } + + public static Builder create() { + return new Builder(); + } + + public static class Builder { + private int mDegrees; + private int mTextColor; + private int mTextSize; + private boolean mTextBold; + private int mDx; + private int mDy; + private Paint.Align mAlign; + + private Builder() { + mDegrees = -30; + mTextColor = Color.parseColor("#33000000"); + mTextSize = 35; + mTextBold = false; + mDx = 100; + mDy = 240; + mAlign = Paint.Align.CENTER; + } + + /** + * 设置水印文字倾斜度 + * + * @param degrees 文字倾斜度(默认:-30) + * @return Builder + */ + public Builder setDegrees(int degrees) { + mDegrees = degrees; + return this; + } + + /** + * 设置水印文字颜色 + * + * @param textColor 文字颜色(默认:#33000000) + * @return Builder + */ + public Builder setTextColor(int textColor) { + mTextColor = textColor; + return this; + } + + /** + * 设置水印文字大小(单位:px) + * + * @param textSize 文字大小(默认:42px) + * @return Builder + */ + public Builder setTextSize(int textSize) { + mTextSize = textSize; + return this; + } + + /** + * 设置水印文字是否加粗 + * + * @param textBold 文字加粗(默认:false) + * @return Builder + */ + public Builder setTextBold(boolean textBold) { + mTextBold = textBold; + return this; + } + + /** + * 设置水印文字X轴间距(单位:px) + * + * @param dx 文字X轴间距(默认:100px) + * @return Builder + */ + public Builder setDx(int dx) { + mDx = dx; + return this; + } + + /** + * 设置水印文字Y轴间距(单位:px) + * + * @param dy 文字Y轴间距(默认:240px) + * @return Builder + */ + public Builder setDy(int dy) { + mDy = dy; + return this; + } + + /** + * 设置水印文字对齐方式 + * + * @param align 对齐方式(默认:Center) + * @return Builder + */ + public Builder setAlign(Paint.Align align) { + mAlign = align; + return this; + } + + /** + * 生成水印全局配置信息 + * + * @return 配置信息 + */ + public WaterMarkInfo generate() { + return new WaterMarkInfo(mDegrees, mTextColor, mTextSize, mTextBold, mDx, mDy, mAlign); + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/widget/WaterMarkManager.java b/app/src/main/java/com/police/policedatasystem/widget/WaterMarkManager.java new file mode 100644 index 0000000..c3089c7 --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/widget/WaterMarkManager.java @@ -0,0 +1,188 @@ +package com.police.policedatasystem.widget; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.graphics.Paint; +import android.view.LayoutInflater; + + +import com.police.policedatasystem.R; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Leon (wshk729@163.com) + * @date 2018/8/24 + *

+ */ +public class WaterMarkManager { + + static WaterMarkInfo INFO = null; + static String[] CONTENT = null; + static List LIST = new ArrayList<>(); + + /** + * 设置水印全局配置信息 + * + * @param info 配置信息 + */ + public static void setInfo(WaterMarkInfo info) { + INFO = info; + } + + /** + * 获取一个满屏水印View + * + * @param activity activity + */ + @SuppressLint("InflateParams") + public static WaterMarkView getView(Activity activity) { + return (WaterMarkView) LayoutInflater.from(activity).inflate(R.layout.view_water_mark, null); + } + + /** + * WaterMarkInfo初始化判断 + */ + private static void assertInitialized() { + if (INFO == null) { + INFO = WaterMarkInfo.create().generate(); + } + } + + /** + * 同步设置全部水印文字信息 + * + * @param content 文字信息 + */ + public static void setText(String... content) { + assertInitialized(); + CONTENT = content; + if (LIST.size() > 0) { + for (WaterMarkView view : LIST) { + if (view != null) { + view.setSyncText(content); + } + } + } + } + + /** + * 同步设置全部水印倾斜角度 + * + * @param degrees 倾斜角度(默认:-30) + */ + public static void setDegrees(int degrees) { + assertInitialized(); + INFO.setDegrees(degrees); + if (LIST.size() > 0) { + for (WaterMarkView view : LIST) { + if (view != null) { + view.setSyncDegrees(degrees); + } + } + } + } + + /** + * 同步设置全部水印字体颜色 + * + * @param textColor 字体颜色(默认:#33000000) + */ + public static void setTextColor(int textColor) { + assertInitialized(); + INFO.setTextColor(textColor); + if (LIST.size() > 0) { + for (WaterMarkView view : LIST) { + if (view != null) { + view.setSyncTextColor(textColor); + } + } + } + } + + /** + * 同步设置全部水印字体大小(单位:px) + * + * @param textSize 字体大小(默认:42px) + */ + public static void setTextSize(int textSize) { + assertInitialized(); + INFO.setTextSize(textSize); + if (LIST.size() > 0) { + for (WaterMarkView view : LIST) { + if (view != null) { + view.setSyncTextSize(textSize); + } + } + } + } + + /** + * 同步设置全部水印字体是否粗体 + * + * @param textBold 是否粗体(默认:false) + */ + public static void setTextBold(boolean textBold) { + assertInitialized(); + INFO.setTextBold(textBold); + if (LIST.size() > 0) { + for (WaterMarkView view : LIST) { + if (view != null) { + view.setSyncTextBold(textBold); + } + } + } + } + + /** + * 同步设置全部水印X轴偏移量(单位:px) + * + * @param dx X轴偏移量(默认:100px) + */ + public static void setDx(int dx) { + assertInitialized(); + INFO.setDx(dx); + if (LIST.size() > 0) { + for (WaterMarkView view : LIST) { + if (view != null) { + view.setSyncDx(dx); + } + } + } + } + + /** + * 同步设置全部水印Y轴偏移量(单位:px) + * + * @param dy Y轴偏移量(默认:240px) + */ + public static void setDy(int dy) { + assertInitialized(); + INFO.setDy(dy); + if (LIST.size() > 0) { + for (WaterMarkView view : LIST) { + if (view != null) { + view.setSignDy(dy); + } + } + } + } + + /** + * 同步设置全部水印对齐方式 + * + * @param align 对齐方式(默认:Center) + */ + public static void setAlign(Paint.Align align) { + assertInitialized(); + INFO.setAlign(align); + if (LIST.size() > 0) { + for (WaterMarkView view : LIST) { + if (view != null) { + view.setSignAlign(align); + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/police/policedatasystem/widget/WaterMarkView.java b/app/src/main/java/com/police/policedatasystem/widget/WaterMarkView.java new file mode 100644 index 0000000..53e453c --- /dev/null +++ b/app/src/main/java/com/police/policedatasystem/widget/WaterMarkView.java @@ -0,0 +1,334 @@ +package com.police.policedatasystem.widget; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.Typeface; +import android.text.TextPaint; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; + +import com.police.policedatasystem.R; + +public class WaterMarkView extends View { + + private static final String DEFAULT_SEPARATOR = "///"; + private TextPaint mTextPaint = new TextPaint(); + + private String[] mText; + private int mDegrees; + private int mTextColor; + private int mTextSize=35; + private boolean mTextBold; + private int mDx; + private int mDy; + private Paint.Align mAlign; + private boolean mSync; + private int textWidth, textHeight; + + public WaterMarkView(Context context) { + this(context, null); + } + + public WaterMarkView(Context context, AttributeSet attrs) { + super(context, attrs); + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.WaterMarkView); + mDegrees = typedArray.getInt(R.styleable.WaterMarkView_water_mark_degree, WaterMarkManager.INFO != null ? WaterMarkManager.INFO.getDegrees() : -30); + String text = typedArray.getString(R.styleable.WaterMarkView_water_mark_text); + if (text != null) { + mText = text.split(DEFAULT_SEPARATOR); + } + mTextColor = typedArray.getColor(R.styleable.WaterMarkView_water_mark_textColor, WaterMarkManager.INFO != null ? WaterMarkManager.INFO.getTextColor() : Color.parseColor("#33000000")); + mTextSize = typedArray.getDimensionPixelSize(R.styleable.WaterMarkView_water_mark_textSize, WaterMarkManager.INFO != null ? WaterMarkManager.INFO.getTextSize() : 42); + mTextBold = typedArray.getBoolean(R.styleable.WaterMarkView_water_mark_textBold, WaterMarkManager.INFO != null && WaterMarkManager.INFO.isTextBold()); + mDx = typedArray.getDimensionPixelSize(R.styleable.WaterMarkView_water_mark_dx, WaterMarkManager.INFO != null ? WaterMarkManager.INFO.getDx() : 100); + mDy = typedArray.getDimensionPixelSize(R.styleable.WaterMarkView_water_mark_dy, WaterMarkManager.INFO != null ? WaterMarkManager.INFO.getDy() : 240); + int align = typedArray.getInt(R.styleable.WaterMarkView_water_mark_align, WaterMarkManager.INFO != null ? WaterMarkManager.INFO.getAlignInt() : 1); + mAlign = align == 0 ? Paint.Align.LEFT : align == 2 ? Paint.Align.RIGHT : Paint.Align.CENTER; + mSync = typedArray.getBoolean(R.styleable.WaterMarkView_water_mark_sync, true); + typedArray.recycle(); + + setBackgroundColor(Color.TRANSPARENT); + mTextPaint.setAntiAlias(true); + mTextPaint.setFlags(Paint.ANTI_ALIAS_FLAG); + mTextPaint.setColor(mTextColor); + mTextPaint.setTextSize(mTextSize); + mTextPaint.setTypeface(mTextBold ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT); + mTextPaint.setTextAlign(mAlign); + + mText = mText == null && mSync ? WaterMarkManager.CONTENT : mText; + + textWidth = 0; + textHeight = 0; + if (mText != null && mText.length > 0) { + for (String s : mText) { + Rect tvRect = new Rect(); + mTextPaint.getTextBounds(s, 0, s.length(), tvRect); + textWidth = textWidth > tvRect.width() ? textWidth : tvRect.width(); + textHeight += (tvRect.height() + 10); + } + } + + if (mSync) { + WaterMarkManager.LIST.add(this); + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + if (mText != null && mText.length > 0) { + int measuredWidth = getMeasuredWidth(); + int measuredHeight = getMeasuredHeight(); + + if (measuredWidth == 0 || measuredHeight == 0) { + return; + } + + int canvasLength = measuredWidth > measuredHeight ? measuredWidth : measuredHeight; + + canvas.save(); + canvas.rotate(mDegrees, measuredWidth / 2, measuredHeight / 2); + + canvas.save(); + int y = 0; + boolean odd = true; + while (y < canvasLength + textHeight) { + int x = odd ? 0 : -(textWidth + mDx) / 2; + while (x < canvasLength + textWidth) { + drawTexts(mText, mTextPaint, canvas, x, y); + x = x + textWidth + mDx; + } + y = y + textHeight + mDy; + odd = !odd; + } + canvas.restore(); + } + } + + private void drawTexts(String[] ss, Paint paint, Canvas canvas, int x, int y) { + Paint.FontMetrics fontMetrics = paint.getFontMetrics(); + float top = fontMetrics.top; + float bottom = fontMetrics.bottom; + int length = ss.length; + float total = (length - 1) * (bottom - top) + (fontMetrics.descent - fontMetrics.ascent); + float offset = total / 2 - bottom; + for (int i = 0; i < length; i++) { + float yAxis = -(length - i - 1) * (bottom - top) + offset; + canvas.drawText(ss[i], x, y + yAxis + 10, paint); + } + } + + /** + * 设置水印文字内容 + * + * @param text 文字内容 + */ + public void setText(String... text) { + mText = text; + + textWidth = 0; + textHeight = 0; + if (mText != null && mText.length > 0) { + for (String s : mText) { + Rect tvRect = new Rect(); + mTextPaint.getTextBounds(s, 0, s.length(), tvRect); + textWidth = textWidth > tvRect.width() ? textWidth : tvRect.width(); + textHeight += (tvRect.height() + 10); + } + } + postInvalidate(); + } + + /** + * 同步设置水印文字内容 + * + * @param text 文字内容 + */ + void setSyncText(String... text) { + if (mSync) { + setText(text); + } + } + + /** + * 设置水印倾斜角度 + * + * @param degrees 倾斜角度(默认:-30) + */ + public void setDegrees(int degrees) { + mDegrees = degrees; + postInvalidate(); + } + + /** + * 同步设置水印倾斜角度 + * + * @param degrees 倾斜角度(默认:-30) + */ + void setSyncDegrees(int degrees) { + if (mSync) { + setDegrees(degrees); + } + } + + /** + * 设置水印字体颜色 + * + * @param textColor 字体颜色(默认:#33000000) + */ + public void setTextColor(int textColor) { + mTextColor = textColor; + mTextPaint.setColor(mTextColor); + postInvalidate(); + } + + /** + * 同步设置水印字体颜色 + * + * @param textColor 字体颜色(默认:#33000000) + */ + void setSyncTextColor(int textColor) { + if (mSync) { + setTextColor(textColor); + } + } + + /** + * 设置水印字体大小(单位:px) + * + * @param textSize 字体大小(默认:42px) + */ + public void setTextSize(int textSize) { + mTextSize = textSize; + mTextPaint.setTextSize(mTextSize); + postInvalidate(); + } + + /** + * 同步设置水印字体大小(单位:px) + * + * @param textSize 字体大小(默认:42px) + */ + void setSyncTextSize(int textSize) { + if (mSync) { + setTextSize(textSize); + } + } + + /** + * 设置水印字体是否粗体 + * + * @param textBold 是否粗体(默认:false) + */ + public void setTextBold(boolean textBold) { + mTextBold = textBold; + mTextPaint.setTypeface(mTextBold ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT); + postInvalidate(); + } + + /** + * 同步设置水印字体是否粗体 + * + * @param textBold 是否粗体(默认:false) + */ + void setSyncTextBold(boolean textBold) { + if (mSync) { + setTextBold(textBold); + } + } + + /** + * 设置水印X轴偏移量(单位:px) + * + * @param dx X轴偏移量(默认:100px) + */ + public void setDx(int dx) { + this.mDx = dx; + postInvalidate(); + } + + /** + * 同步设置水印X轴偏移量(单位:px) + * + * @param dx X轴偏移量(默认:100px) + */ + void setSyncDx(int dx) { + if (mSync) { + setDx(dx); + } + } + + /** + * 设置水印Y轴偏移量(单位:px) + * + * @param dy Y轴偏移量(默认:240px) + */ + public void setDy(int dy) { + this.mDy = dy; + postInvalidate(); + } + + /** + * 同步设置水印Y轴偏移量(单位:px) + * + * @param dy Y轴偏移量(默认:240px) + */ + void setSignDy(int dy) { + if (mSync) { + setDy(dy); + } + } + + /** + * 设置水印对齐方式 + * + * @param align 对齐方式(默认:Center) + */ + public void setAlign(Paint.Align align) { + this.mAlign = align; + postInvalidate(); + } + + /** + * 同步设置水印对齐方式 + * + * @param align 对齐方式(默认:Center) + */ + void setSignAlign(Paint.Align align) { + if (mSync) { + setAlign(align); + } + } + + /** + * 销毁相关页面时调用(切记) + */ + public void onDestroy() { + if (mSync) { + WaterMarkManager.LIST.remove(this); + } + } + + @Override + public boolean dispatchTouchEvent(MotionEvent event) { + return false; + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouchEvent(MotionEvent event) { + return false; + } +} \ No newline at end of file diff --git a/app/src/main/res/color/bottom_nav_colors.xml b/app/src/main/res/color/bottom_nav_colors.xml new file mode 100644 index 0000000..f834a0b --- /dev/null +++ b/app/src/main/res/color/bottom_nav_colors.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/all_10_ccc_bg.xml b/app/src/main/res/drawable/all_10_ccc_bg.xml new file mode 100644 index 0000000..757b52d --- /dev/null +++ b/app/src/main/res/drawable/all_10_ccc_bg.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/all_2_4b8e01_bg.xml b/app/src/main/res/drawable/all_2_4b8e01_bg.xml new file mode 100644 index 0000000..257761d --- /dev/null +++ b/app/src/main/res/drawable/all_2_4b8e01_bg.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/all_2_de7900_bg.xml b/app/src/main/res/drawable/all_2_de7900_bg.xml new file mode 100644 index 0000000..29c0007 --- /dev/null +++ b/app/src/main/res/drawable/all_2_de7900_bg.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/all_2_selected_bg.xml b/app/src/main/res/drawable/all_2_selected_bg.xml new file mode 100644 index 0000000..352767f --- /dev/null +++ b/app/src/main/res/drawable/all_2_selected_bg.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/all_3_ccc_bg.xml b/app/src/main/res/drawable/all_3_ccc_bg.xml new file mode 100644 index 0000000..a4e3f93 --- /dev/null +++ b/app/src/main/res/drawable/all_3_ccc_bg.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/all_7_fff_bg.xml b/app/src/main/res/drawable/all_7_fff_bg.xml new file mode 100644 index 0000000..65ffac7 --- /dev/null +++ b/app/src/main/res/drawable/all_7_fff_bg.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/all_7_line_ccc_bg.xml b/app/src/main/res/drawable/all_7_line_ccc_bg.xml new file mode 100644 index 0000000..f7fd2cb --- /dev/null +++ b/app/src/main/res/drawable/all_7_line_ccc_bg.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/all_7_main_bg.xml b/app/src/main/res/drawable/all_7_main_bg.xml new file mode 100644 index 0000000..5375343 --- /dev/null +++ b/app/src/main/res/drawable/all_7_main_bg.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/back.png b/app/src/main/res/drawable/back.png new file mode 100644 index 0000000000000000000000000000000000000000..76e3e82c86223a01bdf01855ccc955db193d0a60 GIT binary patch literal 688 zcmV;h0#E&kP)Cfog`K$GV-HS-=ov_oO|zc?>YCgnV#=_&wb52KhE<#H*2@sG?dxE75RB^QiI4i zFhd?6@A6vWGgBcZA5ud@z(a+61%^{XL-L=@Qpg(MRVrw(0C{d6q=5Q?`wIC1thY!C z$RK0DJcVok9=nY((DVXiOgGns`heRC`2}naA$6fXc}*56WQ){;sR|V#H@t2qRiG)r zHHG{Ewv{1NfDCdASgw$rz*Vn1kWL_rtOy|Iz3!ZpL6d{h=!1|0QPL_p?(djrTJuR9Vt&@@8eU5D(@nOBWWcdOOvQJdvLU;wz28XA|4 zbE(3n0r$KW5fC!;4G3Vf1n31Gc&j2HACt8u*2&Pq{^f^A#=ndr`9Fk%B5J<+55X3OG4OouR8*A zv1jT!XMjy!cLZdyb-)X!)+4iE5Q{nSeUZa(M_B9`)?%*}b`e;a60+E8;Ehx3l@rK+ zEY*F6&vMaREajaOi@jBtIVCPmeJ{vhW`}?0)TRO#nz+05UcM+@tiK7!#hw5kfsucl Wt%I$Vk#$`F0000x;^#6U* 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